MongoDB 聚合管道:计算匹配文档中列表字段中单词的出现次数?

MongoDB aggregation pipeline: counting occurrences of words in list field from matching documents?

这是我正在尝试做的一个简化示例。我的文档都有各种各样的东西和一个 keywords 字段,其中包含一个字符串列表作为值。 (列表可以包含重要的重复项。)假设以下文档与查询匹配:

{'original_id': 33, 'keywords': ['dog', 'cat', 'goat', 'dog']},
{'original_id': 34, 'keywords': ['dog', 'kitten', 'goat', 'moose']},
{'original_id': 35, 'keywords': ['moose', 'elk']}

我想取回找到的关键字的映射以及匹配文档集中每个关键字的出现次数:

{'dog': 3, 'cat': 1, 'goat':2, 'kitten': 1, 'moose': 2, 'elk': 1}

(请注意文档 33 中的 dog 被计算了两次。)

我目前正在通过 PyMongo 执行此操作,方法是创建 Counter、调用 collection_name.find(...),然后遍历所有文档以使用每个关键字字段更新计数器。但我想通过在 MongoDB.

内进行来提高流程效率

在聚合管道中可以进行这种计数吗?如果是,怎么做?

  • $unwind解构keywords数组
  • $groupkeywords 计算总计
  • $group by null 构造键值对数组
  • $arrayToObject 将上述数组转换为对象键值格式
  • $replaceRoot 将上面转换后的对象替换为 root
db.collection.aggregate([
  { $unwind: "$keywords"c },
  {
    $group: {
      _id: "$keywords",
      count: { $sum: 1 }
    }
  },
  {
    $group: {
      _id: null,
      keywords: {
        $push: {
          k: "$_id",
          v: "$count"
        }
      }
    }
  },
  { $replaceRoot: { newRoot: { $arrayToObject: "$keywords" } } }
])

Playground