我有一个资源集合,其中包含一个非唯一的群集字段(数字)。数据看起来像:
{
{
_id: "0"
cluster: 15
},
{
_id: "1"
cluster: 4
},
{
_id: "2"
cluster: 15
},
{
_id: "3"
cluster: 8
},
...
}
我的目标是为每个集群匹配找到n个资源。例如,假设我要获得五个与群集1相匹配的资源,八个与群集2相匹配的资源,以及七个与群集3相匹配的资源。
目前,我可以通过发送3个单独的请求来解决该问题,例如:
db.resources.find({cluster: 1}).limit(5)
不幸的是,随着我要搜索的集群数量的增加,这变得非常低效。此外,我知道我可以按群集进行聚合和分组,但据我所知,这将仅使我能够访问每个群集的第一个(不是第n个)资源。任何帮助将不胜感激!
答案 0 :(得分:0)
您可以将聚合管道与$ facet一起使用,并为$match
操作中的每个集群并行运行$limit
和$facet
阶段。最后合并$ facet阶段中的所有数组。
尝试一下:
对于集群:1,3(分别限制为2,3),您可以使用以下查询:
db.collection.aggregate([
{
$facet: {
"cluster1": [
{
$match: {
"cluster": 1
}
},
{
$limit: 2
}
],
"cluster2": [
{
$match: {
"cluster": 3
}
},
{
$limit: 3
}
]
}
},
{
$project: {
items: {
$concatArrays: [
"$cluster1",
"$cluster2"
]
}
}
},
{
$unwind: "$items"
},
{
$replaceRoot: {
newRoot: "$items"
}
}
])
检查Mongo Playground上的结果
要概括上述聚合查询,您可以根据包含不同facetQuery
及其各自{{1}的传入对象(concatArrays
)来构造obj
和cluster
}}。
limits
答案 1 :(得分:-1)
这是我所知的最短的动态答案 https://mongoplayground.net/p/Ni-irGhtp85
top_n