我有一个文档集合,我试图计算有多少文档包含数组中的每个元素,该元素本身是数组中嵌套文档的一部分。
文件示例:
[
{
"title": "fruit mix 1",
"fruit_details": [
{
"fruit_names": [
"strawberry",
"banana"
],
"category": "berries"
},
{
"fruit_names": [
"strawberry",
"apple",
"mango
],
"category": "red",
}
]
},
{
"title": "fruit mix 2",
"fruit_details": [
{
"fruit_names": [
"banana",
"mango"
],
"category": "tropical",
}
]
},
{
"title": "fruit mix 3",
"fruit_details": [
{
"fruit_names": [
"banana",
"lemon"
],
"category": "yellow",
},
{
"fruit_names": [
"banana"
],
"category": "long",
},
]
},
]
我想要一个聚合管道返回:
[
{
"_id": "banana",
"count": 3
},
{
"_id": "mango",
"count": 2
},
{
"_id": "lemon",
"count": 1
},
{
"_id": "strawberry",
"count": 1
},
{
"_id": "apple",
"count": 1
},
]
香蕉出现在所有3个顶级文档中,因此计数为3,芒果只出现在2,以此类推。
我不确定如何在不重复计算fruit_details数组中多个子文档中出现的元素的情况下完成此操作。例如,草莓在水果混合1文档中出现两次,但只应计数一次。
到目前为止,我已经尝试使用$setUnion和$group来计算唯一的出现次数。这样做的问题是$setUnion联合每个fruit_names数组,而不是该数组中的每个元素。它也不能解决重复计算的问题。
db.collection.aggregate([
{
$project: {
fruit: {
$setUnion: [
"$fruit_details.fruit_names",
],
},
},
},
{
$unwind: "$fruit",
},
{
$group: {
_id: "$fruit",
count: {
$sum: 1,
},
},
},
{
$sort: {
_id: 1,
},
},
])
1条答案
按热度按时间ct2axkht1#
我认为这里的关键,至少对于一种方法来说,是使用the
$reduce
operator。如果我们将初始管道阶段修改为如下所示:然后它会产生你想要的输出。Playground demonstration here。
(我还更改了
$sort
,以便输出与您请求的内容相匹配。)