在mongodb中如何给列表按时间排序

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在mongodb中如何给列表按时间排序相关的知识,希望对你有一定的参考价值。

参考技术A 时间降序:

db.somecollection.find().sort( time : -1 );

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

【中文标题】如何将项目存储在 MongoDb 的排序列表中?【英文标题】:How to store items in a sorted list in MongoDb? 【发布时间】:2018-08-07 08:58:19 【问题描述】:

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

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

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

products_published
products_unpublished

然后,每天,shift() 将来自 products_publishedunshift() 的项目放入 products_unpublished,同时将 pop() 来自 products_unpublishedpush() 的项目放入 @987654331 @:

也许是一个非常幼稚的轮换尝试。但这似乎很简单。

最后的要求是这个旋转顺序必须可以通过一些 UI 进行编辑。

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

我真的不想在我的文档上维护我自己的order 属性,因为每次轮换我都必须增加每个文档的order

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

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

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

有什么建议吗?

【问题讨论】:

【参考方案1】:

添加 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_dates 以使新订单生效。

例子:

// 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更新

【讨论】:

我不想使用硬编码的日期,因为未来的轮换频率可能会变为一天两次、一天三次等。 另外,我认为您的解决方案甚至都行不通。用户需要能够修改轮换顺序...不仅仅是“初始”顺序。 ISODate 具有毫秒精度。对不起,如果名称有误导性。 在轮换期间轮换期间弄乱轮换顺序是一个值得商榷的功能,但我将其留给企业来处理后果。您如何在轮换期间重新定义顺序?移动列表中的一项?更新整个粉色堆栈的顺序? 我知道它具有毫秒精度。我宁愿将轮换间隔逻辑保留在单独的 rotator-microservice 中,并且只在数据库级别保留轮换 order 。旋转是恒定的,因此当然任何重新排序都会在旋转期间发生。最简单的方法是简单地交换任意两个产品的位置。

以上是关于在mongodb中如何给列表按时间排序的主要内容,如果未能解决你的问题,请参考以下文章

MongoD基础之六 索引

如何在 mongoDb 中按多个字段排序

MongoDB - 营业时间,按当天排序

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

如何在 MongoDB 中按日期对集合进行排序?

如何在 mongodb 配置文件中设置授权?