Javascript 如何在MongoDb中将项目存储在排序列表中?
我正在使用MongoDb构建一个出版物轮换解决方案 例如,客户拥有1000种产品,并且在任何时候,订阅者都可以使用其中的200种产品。其余的(800)应采用轮换模式,即每天发布一个产品,另一个未发布,这样在800天后,就会发生完全轮换 我最初的想法是简单地将ID引用存储在两个新集合中:Javascript 如何在MongoDb中将项目存储在排序列表中?,javascript,json,mongodb,mongoose,nosql,Javascript,Json,Mongodb,Mongoose,Nosql,我正在使用MongoDb构建一个出版物轮换解决方案 例如,客户拥有1000种产品,并且在任何时候,订阅者都可以使用其中的200种产品。其余的(800)应采用轮换模式,即每天发布一个产品,另一个未发布,这样在800天后,就会发生完全轮换 我最初的想法是简单地将ID引用存储在两个新集合中: products_published products_unpublished 然后,每天,shift()从products\u发布的一个项目和unshift()将其转换为products\u未发布的,同时po
products_published
products_unpublished
然后,每天,shift()
从products\u发布的一个项目和unshift()
将其转换为products\u未发布的
,同时pop()
从products\u未发布的
和push()
将其转换为products\u发布的
:
可能是一次非常天真的轮换尝试。但这似乎很简单
最后一个要求是,这个旋转顺序必须通过一些UI进行编辑
问题在于MongoDb似乎不能保证自然的秩序,在集合中的确切位置插入文档、移动文档等也不容易
我真的不想在我的文档上维护自己的order
属性,因为每次轮换时,我都必须增加每个文档的order
我还考虑过将所有这些数据保存在一个包含两个数组的文档中,因为文档中的数组本身确实以安全的方式保持顺序。然而,这感觉很脏,而且很容易出现未来的问题
经过大量的谷歌搜索,我还没有找到一个关于如何使用MongoDb维护有序集合的好答案
我不想使用硬编码日期,因为未来轮换频率可能会变为每天两次、每天三次,等等
有什么建议吗?添加两个属性:顺序
和发布日期
。
前者供用户定义初始订单。后者供您旋转
获取下一个查询的查询:
db.collection.find({}).sort({published_date: 1, order: 1}).limit(1)
推送/弹出更新:
db.collection.update({_id}, {$set:{published_date: new ISODate()}})
在订单
更改时,删除所有发布日期
s以使新订单生效
例如:
// 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
如果您不喜欢日期作为一个自然的自动递增值,您可以单独使用order字段
推送/弹出更新将是:
db.collection.update({_id}, {$inc:{order: <number of documents in rotation>}})
如果它符合单个文档的16MB限制
数组中元素的顺序保留为:,您可以使用定期/更新我不想使用硬编码日期,因为旋转频率将来可能会更改为每天两次、每天三次等。此外,我认为您的解决方案甚至不起作用。用户需要能够修改旋转顺序。。。不仅仅是“初始”订单。ISODate具有毫秒精度。很抱歉,如果名称有误导性。在轮换过程中弄乱轮换顺序是一个值得怀疑的功能,但我将其留给企业来处理后果。如何在旋转过程中重新定义顺序?移动列表中的一项?更新整个粉色堆栈的顺序?我知道它有毫秒的精度。我宁愿在单独的rotator微服务中保留旋转间隔逻辑,而只是在数据库级别保留旋转顺序。旋转是恒定的,因此在旋转过程中当然会发生任何重新排序。最简单的方法是简单地交换任意两种产品的位置。
{
refs: [
product_id,
product_id,
product_id,
]
}