【问题标题】:MongoDB pagination with grouped item带有分组项目的MongoDB分页
【发布时间】:2015-06-12 16:22:28
【问题描述】:

我正在将消息传递模块构建到现有的网络应用程序中。我们将消息存储在 mongo 中,其数据结构类似于:

{
  id: "",
  inResponseToMessageId: ""
  to: []
  cc: []
  bcc: []
  subject: ""
  body: ""
  owners: [{id:4, status:"read", folder:"inbox"}, {id:1, status:'unread', folder:'inbox'}]
  dateSent:
}

客户希望我们能够在对话视图单一视图中显示消息。

我无法找到一个有效的查询,可以

  1. 返回按消息线程分组的结果。
  2. 与分页配合得很好。
  3. 可按日期和主题排序。

我可以根据需要修改数据结构以使其正常工作。

以下是一些可能的解决方案,但它们似乎都达不到要求:

  • 将消息存储为线程对象的子对象。
  • 给每条消息添加一个threadId,然后按threadId查询和分组。
  • 创建一些有帮助的元信息对象。

标准 mongo group$group 函数的问题是,我想当集合很大时它的性能会很差。我们预计集合中有数亿条消息。

【问题讨论】:

  • 我知道这不是您问的问题,但是:Mongo 真的是必需品,还是您可以灵活选择文档存储?您描述的问题实际上是一个关系问题...如果您可以选择另一种存储解决方案,那么我建议使用 OrientDB 而不是 Mongo,因为它可以充当文档存储,并且您的双手不会像现在这样被束缚。无论您决定采用哪种方式,我都建议您实际运行一些基准测试,看看您的预期是否与实际表现相符!
  • @easuter。感谢您的回复。我很高兴使用关系数据库,但我认为它不会解决问题。您能否详细说明关系模型将如何提供帮助?
  • 首先,很抱歉回复晚了!如果您要存储严格分层的数据并且确定您的架构(呵呵...)将永远是静态的,那么像 Mongo 这样的文档存储非常棒。这个问题的一个经典例子是Diaspora's initial use of MongoDB as the project's storage,我强烈推荐阅读它。回到最后一点:您不确定您的客户的需求是否会在未来发生变化,到那时您可能已经“将自己编码到了一个角落”,这使得切换到其他东西非常痛苦。

标签: performance mongodb pagination


【解决方案1】:

在您的消息中添加threadId

返回按消息线程分组的结果。

您可以按主题查找消息

db.messages.find({ "threadId" : id })

我认为没有必要按照$group 运算符的意义对它们进行分组。

与分页配合得很好。

消息的分页顺序是什么?如果您对一个独特的字段进行排序,则分页效果很好。 dateSent 应该是唯一的,如果您将其保持在毫秒精度,那么您可以对其进行分页。

// page 1
db.messages.find({ "threadId" : id }).sort({ "dateSent" : -1 }).limit(25)
// page 2
db.messages.find({ "threadId" : id, "dateSent" : { "$gt" : <25th date sent> } }).sort({ "dateSent" : -1 }).limit(25)

可按日期和主题排序。

谁按主题对邮件进行排序?无论如何,如果您想按日期或主题顺序检索消息,这只是创建正确索引的问题。根据您的要求,您可能会为客户端视图执行此排序,其中可能不需要让数据库对结果进行排序。客户端可以改为对返回的子集执行此操作。

【讨论】:

  • 这行不通。您的查询将返回消息,但它们不会按线程分组。如果最近的 25 条消息都属于同一个线程,那么它将只返回 1 个线程的消息,而不是 25 个线程。收件箱需要显示 25 个线程而不是 1 个。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-30
  • 2020-10-30
  • 2019-10-18
  • 1970-01-01
  • 2014-11-29
相关资源
最近更新 更多