我正在使用MongoDb构建出版物轮换解决方案。

例如,客户拥有1000种产品,并且在任何时候,订户应该可以使用其中200种产品。其余(800)应该采用轮换模式,每天发布一种产品而另一种未发布,这样在800天后发生了一次完整的轮换。

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

products_published
products_unpublished

然后,每天,将shift()中的一个项目products_published并将其unshift()编码为products_unpublished,同时将pop()中的一个项目products_unpublished并将其push()变为products_published:

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

也许是非常幼稚的旋转尝试。但这似乎很简单。

最终要求是必须通过某些UI可以编辑此旋转顺序。

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

我并不是很想在文档上维护自己的order属性,因为每次旋转我都必须增加每个文档的order

我还考虑了将所有这些数据保存在具有两个数组的单个文档中,因为文档内部的数组本身确实以安全的方式保留了顺序。但是,这感觉很脏并且容易出现将来的问题。

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

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

有什么建议吗?

最佳答案

添加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更新

关于javascript - 如何在MongoDb中的排序列表中存储项目?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49013312/

10-09 20:12
查看更多