假设我有一个包含多个具有以下结构的文档的集合:
{
_id: "id12345",
objects: ["123","456", "789"]
}
现在,我想创建一个查询,在该查询中我传递一个对象数组,并获取该数组中每个元素在文档中的出现次数,如下所示:
查询输入:["123","321"]
输出:
{
"123": 1,
"321": 0
}
我只想通过传递一个数组的一个查询来执行此操作,我知道我可以轻松地一个接一个地而不是一个数组地执行此操作,但这不是目的。
答案 0 :(得分:1)
您可以在3.6中使用以下汇总。
$match
过滤输入数组和对象数组之间至少有一个数组匹配的文档。
$project
与$map
迭代输入数组,并与对象数组中的每个数组元素进行比较,并根据匹配结果返回0和1。
$unwind
和$group
,以计算所有文档中数组元素的出现。
db.colname.aggregate([
{"$match":{"objects":{"$in":["123","321"]}}},
{"$project":{
"keyandcount":{
"$map":{
"input":["123","321"],
"in":{
"k":"$$this",
"v":{"$cond":[{"$in":["$$this","$objects"]},1,0]}
}
}
}
}},
{"$unwind":"$keyandcount"},
{"$group":{"_id":"$keyandcount.k","count":{"$sum":"$keyandcount.v"}}}
])
您可以在最后两个阶段添加以下内容,以格式化对键值对的响应。
{"$group":{_id: null,"keycountpair":{"$mergeObjects":{"$arrayToObject":[[["$_id","$count"]]]}}}},
{"$replaceRoot":{"newRoot":"$keycountpair"}}
答案 1 :(得分:0)
通常,获取此信息的查询非常简单,因为不建议在数据层中将值切换为键,而在表示层中将其切换为键。
所以这个:
db.collection.aggregate([
{
$unwind: "$objects"
},
{
$group: {
_id: "$objects",
count: {
$sum: 1
}
}
}
])
将为您提供数字_id
和一个count
字段以及出现次数。然后,您可以在自己的应用程序中对其进行按摩,使其以您想要的方式呈现。