json MongoDB -计算嵌套数组包含每个值的对象的数量

guykilcj  于 2023-06-25  发布在  Go
关注(0)|答案(1)|浏览(135)

我有一个文档集合,我试图计算有多少文档包含数组中的每个元素,该元素本身是数组中嵌套文档的一部分。
文件示例:

[
{
  "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,
    },
  },
])
ct2axkht

ct2axkht1#

我认为这里的关键,至少对于一种方法来说,是使用the $reduce operator。如果我们将初始管道阶段修改为如下所示:

{
    $project: {
      fruit: {
        "$reduce": {
          "input": "$fruit_details",
          "initialValue": [],
          "in": {
            "$setUnion": [
              "$$value",
              "$$this.fruit_names",
              
            ]
          }
        }
      }
    }
  },

然后它会产生你想要的输出。Playground demonstration here
(我还更改了$sort,以便输出与您请求的内容相匹配。)

相关问题