如何在MongoDb的排序列表中存储项目?

时间:2018-02-27 16:20:49

标签: javascript json mongodb mongoose nosql

我正在使用MongoDb构建一个发布轮换解决方案。

例如,客户有1000种产品,并且在任何时候,订户都应该有200种这样的产品。其余的(800)应该是旋转模式,每天发布一个产品而另一个未发布,这样800天后就会发生完全旋转。

我最初的想法是将ID引用存储在两个新集合中:

products_published
products_unpublished

然后,每天shift() products_publishedunshift()products_unpublishedpop(),同时products_unpublished来自push()的项目products_published {1}}和order order

enter image description here

非常天真的轮换尝试,也许吧。但这似乎很简单。

最后的要求是必须通过某些UI编辑此轮换顺序。

问题在于MongoDb似乎不保证自然顺序,也不容易在集合中的确切位置插入文档,移动它们等等。

我真的不想在我的文档上维护自己的{{1}}属性,因为每次轮换都需要增加每个文档的{{1}}。

我还考虑将所有这些数据保存在一个包含两个数组的文档中,因为文档中的数组以安全的方式保存顺序。然而,这感觉很脏并且容易出现未来的问题。

经过大量的谷歌搜索后,我还没有找到一个关于如何使用MongoDb维护有序集合的好答案。

我不想使用硬编码日期,因为将来轮换频率可能会改变为每天两次,一天三次等等。

有任何建议吗?

1 个答案:

答案 0 :(得分:0)

添加2个属性:orderpublished_date。 前者是供用户定义初始订单。后者是你旋转的。

获取下一个的查询:

db.collection.find({}).sort({published_date: 1, order: 1}).limit(1)

推/弹更新:

db.collection.update({_id}, {$set:{published_date: new ISODate()}})

order更改后,删除所有published_date以使新订单生效。

示例:

// initial data
db.collection.insert([
  {_id:1, order:2},
  {_id:2, order:1},
  {_id:3, order:3}
])

// pick the first document
db.collection.find({}).sort({published_date: 1, order: 1}).limit(1)
// returns you {_id:2, order:1}

// rotating it:
db.collection.update({_id:2}, {$set:{published_date: new ISODate()}})

// pick the first document
db.collection.find({}).sort({published_date: 1, order: 1}).limit(1)
// returns you {_id:1, order:2}

// rotating it:
db.collection.update({_id:1}, {$set:{published_date: new ISODate()}})

// pick the first document
db.collection.find({}).sort({published_date: 1, order: 1}).limit(1)
// returns you {_id:3, order:3}

// rotating it:
db.collection.update({_id:1}, {$set:{published_date: new ISODate()}})

// pick the first document
db.collection.find({}).sort({published_date: 1, order: 1}).limit(1)
// returns you {_id:2, order:1, published_date: 2018-02-27T18:28:20.330Z}

etc, etc, etc until end of days at 15:30:08 on Sunday, December 4th in the year 292,277,026,596 AC

如果您不希望将日期作为自然自动增量值,则可以单独使用订单字段。

推/弹更新将是:

db.collection.update({_id}, {$inc:{order: <number of documents in rotation>}})

但是,它需要对$dec计时器进行一些内务处理,并且使单个文档的移位变得复杂。

或者,您可以考虑将ID保留在单个文档中,而不是集合中:

{
    refs: [
        product_id,
        product_id,
        product_id,
    ]
}

如果它符合单个文档的16MB限制。

保留数组中元素的顺序:http://www.rfc-editor.org/rfc/rfc7159.txt,您可以使用常规$push / $pop更新