我如何在mongoDB中按对每个组进行排序和限制。
考虑以下数据:
Country:USA,name:xyz,rating:10,id:x
Country:USA,name:xyz,rating:10,id:y
Country:USA,name:xyz,rating:10,id:z
Country:USA,name:abc,rating:5,id:x
Country:India,name:xyz,rating:5,id:x
Country:India,name:xyz,rating:5,id:y
Country:India,name:abc,rating:10,id:z
Country:India,name:abc,rating:10,id:x
现在,我将按国家分组,按评级排序,并将每组的数据限制为2。
所以答案是:
Country:USA
name:xyz,rating:10,id:x
name:xyz,rating:10,id:y
Country:India
name:abc,rating:10,id:x
name:abc,rating:10,id:z
我想只使用聚合框架来实现这一点。
我试图包括排序的评级,但简单的查询后处理没有结果。
您最好的选择是为每个“国家”运行单独的查询(理想情况下是并行)并返回组合结果。查询非常简单,只需在对评级值应用排序后返回前2个值,即使您需要执行多个查询以获得完整的结果,也会执行得非常快。
聚合框架现在甚至在不久的将来都不适合这种情况。问题是没有这样的操作符以任何方式“限制”任何分组的结果。因此,要做到这一点,您基本上需要将所有内容推送到一个数组中,并从中提取“前n个”值。
当前需要执行的操作非常可怕,核心问题是,在大多数真实数据源上,结果可能会超过BSON对每个文档16MB的限制。
此外,由于您现在必须执行的操作方式,此操作也很复杂。但仅用两个项目进行演示:
db.collection.aggregate([
// Sort content by country and rating
{ "$sort": { "Country": 1, "rating": -1 } },
// Group by country and push all items, keeping first result
{ "$group": {
"_id": "$Country",
"results": {
"$push": {
"name": "$name",
"rating": "$rating",
"id": "$id"
}
},
"first": {
"$first": {
"name": "$name",
"rating": "$rating",
"id": "$id"
}
}
}},
// Unwind the array
{ "$unwind": "results" },
// Remove the seen result from the array
{ "$redact": {
"$cond": {
"if": { "$eq": [ "$results.id", "$first.id" ] },
"then": "$$PRUNE",
"else": "$$KEEP"
}
}},
// Group to return the second result which is now first on stack
{ "$group": {
"_id": "$_id",
"first": { "$first": "$first" },
"second": {
"$first": {
"name": "$results.name",
"rating": "$results.rating",
"id": "$results.id"
}
}
}},
// Optionally put these in an array format
{ "$project": {
"results": {
"$map": {
"input": ["A","B"],
"as": "el",
"in": {
"$cond": {
"if": { "$eq": [ "$$el", "A" ] },
"then": "$first",
"else": "$second"
}
}
}
}
}}
])
这会得到结果,但这不是一个很好的方法,而且随着迭代次数的增加,会变得更加复杂,以获得更高的限制,甚至在某些情况下分组返回的结果可能少于n。
截至编写时,当前的开发系列(3.1. x)有一个$切片
运算符,它使这变得更简单,但仍然具有相同的“大小”陷阱:
db.collection.aggregate([
// Sort content by country and rating
{ "$sort": { "Country": 1, "rating": -1 } },
// Group by country and push all items, keeping first result
{ "$group": {
"_id": "$Country",
"results": {
"$push": {
"name": "$name",
"rating": "$rating",
"id": "$id"
}
}
}},
{ "$project": {
"results": { "$slice": [ "$results", 2 ] }
}}
])
但基本上,直到聚合框架有某种方法“限制”$ush
或类似的分组“限制”运算符产生的项目数量,那么聚合框架并不是这种类型的问题的最佳解决方案。
像这样的简单查询:
js prettyprint-override">db.collection.find({ "Country": "USA" }).sort({ "rating": -1 }).limit(1)
为每个不同的国家运行,理想情况下通过线程的事件循环并行处理,并结合结果产生当前最优化的方法。它们只获取所需的内容,这是聚合框架在这种分组中尚无法处理的大问题。
因此,请寻找支持,以最理想的方式为您选择的语言执行此“组合查询结果”,因为这将比将此应用于聚合框架要简单得多,性能也要高得多。
我有一个具有以下模式的待售项目集合: 我继承了一个聚合查询,它返回匹配类别的项目,按商家分组,组按组中的最大评级排序: 在此之后,代码继续按评级对每组中的项目进行排序,并删除除每组中排名前2位之外的所有项目。 作为聚合函数的一部分,是否可以在组内执行此排序和限制,以便聚合只返回每组中评级最高的两个项目?
例如,我有一个收藏: 如何在MongoDB中进行查询以按分组,然后按排序并以进行。我想得到这样的:
本文向大家介绍在MongoDB中执行聚合排序?,包括了在MongoDB中执行聚合排序?的使用技巧和注意事项,需要的朋友参考一下 您可以将method和$sort()运算符一起使用。为了理解这个概念,让我们用文档创建一个集合。使用文档创建集合的查询如下- 在method的帮助下显示集合中的所有文档。查询如下- 以下是输出- 这是对MongoDB聚合排序的查询。 情况1-每当您希望结果按降序排列时。查
在MongoDB聚合管道中,从一个阶段到另一个阶段的记录流一次发生一个/批(或者)将等待当前阶段完成整个收集,然后再将其传递到下一个阶段? 例如,我有一个包含以下示例记录的集合类测试 我总共有大约100名学生的1000条记录,我有以下汇总查询 我有以下问题。 排序顺序在最终结果中丢失。如果我在$group之后放置另一个排序,则结果会正确排序。这是否意味着$group不维护之前的排序顺序? 我想将结
给java类一些东西 我有一张物品清单 我希望能够对它们进行排序,这样它们就可以按照每个父对象的虚数的累积和排序,然后再按照虚数排序。 所以我最终 我知道用parentKey和sum of noThings映射它是 我想,也许包装我的Something类并获得每个父项的总密钥可能会在某种程度上起作用。 但看起来工作量很大,不太优雅。 如有任何意见/想法,将不胜感激。
也许有人知道。。我的mongoDB集合中的每个文档如下所示: 如何找到每个组中强度. a和强度. b之和最大的前10个文档? 示例:我有这样的文件: 我想得到结果: 总之,在本例中,我希望得到按“group”字段分组的结果,并仅从每组中选择前两个字段总数最大的“a”和“b”文档。这是否可行? 到目前为止,我做到了: 但如何排序和限制每个组的数组“用户”中的元素数?