Mongo查询对象内最长数组的查询

19

目前我的应用程序在Mongo中的对象设置为这样(这是一个简化的例子,我为了清晰起见删除了一些不相关的字段):

{
    "_id" : ObjectId("529159af5b508dd71500000a"),
    "c" : "somecontent",
    "l" : [
        {
            "d" : "2013-11-24T01:43:11.367Z",
            "u" : "User1"
        },
        {
            "d" : "2013-11-24T01:43:51.206Z",
            "u" : "User2"
        }
     ]
}
我想要做的是运行一个查找查询以返回在“l”下拥有最高数组长度的对象,并按从高到低排序,最多返回25个结果。有些对象可能只有1个对象在数组中,有些可能有100个。我想找出哪些对象在“l”下拥有最多的对象。我刚接触Mongo,一直到这个点为止,我已经解决了所有其他问题,但我就是无法弄清楚获取这个特定查询所需的正确参数。我被弄糊涂了如何处理计算数组的长度、排序等问题。我可以通过解析集合中的所有内容手动编写代码,但我相信Mongo有更有效的方法来完成此任务。如果有人知道更高级的查询资源或可以帮助我,我将不胜感激,因为这是最后一块缺失的部分! :-)
另外提一下,node.js和Mongo一起使用非常棒,我希望很早就开始同时使用它们了。

如果你正在匆忙中寻找一个非常hacky的解决方案,那么你可以使用 {'l.0': { $exists: true } } 并不断增加0到1到2...直到找到具有最多项的文档。虽然这对于想要按最高->最低排序的人没有帮助。 - Raphael
3个回答

25

使用聚合框架,以下是方法:

db.collection.aggregate( [
  { $unwind : "$l" },
  { $group : { _id : "$_id", len : { $sum : 1 } } },
  { $sort : { len : -1 } },
  { $limit : 25 }
] )

谢谢!正是我所需要的。我原以为聚合是正确的方法,但不确定如何正确使用它。非常感激 :-) - mike029

2
使用现有的模式没有简单的方法来完成这个任务。原因是 MongoDB 中没有找到数组长度的大小。是的,你有$size运算符,但它的工作方式只是查找特定长度的所有数组。
因此,你无法根据数组的长度对查询进行排序。唯一合理的方法是在模式中添加附加字段,该字段将保存数组的长度(你将为每个文档拥有类似于“l_length: 3”的字段)。好消息是,你可以通过查看相关答案轻松做到这一点,并且在修改数组时只需要确保增加或减少该值即可。
当你添加了这个字段后,就可以轻松地按该字段进行排序,而且你还可以利用索引。

1

没有直接的方法来做到这一点,

您可以尝试使用$size在文档中添加大小字段,

  • $addFields 添加新字段total以获取l数组中的总元素数
  • $sort 按降序排列total
  • $limit 选择单个文档
  • $project 如果不需要,则删除total字段
db.collection.aggregate([
  { $addFields: { total: { $size: "$l" } } },
  { $sort: { total: -1 } },
  { $limit: 25 }
  // { $project: { total: 0 } }
])

游乐场


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接