mongodb - 使用 MongoDB 的新聚合框架搜索和计数标签的有效方法是什么?

标签 mongodb aggregation-framework

我正在尝试使用新的 AF 来迁移 Map/reduce。我有数百万个这样的对象:

{
 _id: ObjectID,
 owner: 1,
 tags: [
   {text: "dog", score: 5}, 
   {text: "cat", score: 3}, 
   {text: "hamster", score:1}]
}

{
 _id: ObjectID,
 owner: 2,
 tags: [
   {text: "cat", score: 8}, 
   {text: "fish", score: 4}]
}

我想做一个报告,其中包含所有者为 X 的“cat”和“fish”的所有匹配项的计数。

到目前为止,我的管道假设输入标签 ["cat", "fish"] 看起来像:

{
  $match: { owner: X, $in: {"tags.text": ["cat", "fish"]}}
}, {
  $project: {text: "$tags.text"},
}, {
  $unwind: "$text",
}, {
  $match: {"text": {$in: {"tags": ["cat", "fish"]}}
}, {
  $group: {"_id": "$text", "total: {"$sum": 1}}
}

第一个 $match 只是缩小到所有这百万个对象的子集 - 因为我有一个关于所有者和“tags.txt”的索引。

此管道对于少量标签运行良好,但我需要能够传递 100-1000 个“标签”并快速获得结果。似乎投影出并展开所有标签,而只是在下一个匹配步骤中过滤 90% 的标签,效率一定很低。

有没有更有效的方法?也许重新排列管道步骤?

最佳答案

这对我来说看起来不错,除了一些拼写错误以及每个 $match 管道操作中 $in 运算符的使用可能应该是:

{
  $match: {owner: X, "tags.text": {$in: ["cat", "fish"]}}
}, {
  $project: {text: "$tags.text"}
}, {
  $unwind: "$text"
}, {
  $match: {"text": {$in: ["cat", "fish"]}}
}, {
  $group: {"_id": "$text", "total": {"$sum": 1}}
}

本质上,您希望在管道中尽早使用 $match 来限制管道中稍后处理的文档数量。 owner 和特定标签的匹配可以实现这一点。您还需要确保您的 $match (相当于 .find())使用适当的索引。

关于mongodb - 使用 MongoDB 的新聚合框架搜索和计数标签的有效方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12514043/

相关文章:

node.js - Mongoose 模型在填充后获得未定义的属性

node.js - 如何在 CentOS 服务器上安装 Parse Server?

mongodb - Mongoose- 使用特定项目将数组中的数据搜索/过滤到另一个数组中

mongodb - 查找其数组字段包含给定数组的至少 n 个元素的文档

具有最大日期的 mongodb 聚合框架查询

mongodb - 合并文档及其嵌套数组及其嵌套数组

mongodb - 如何在grails mongodb插件中按嵌入式对象的属性过滤

php - 使用映射和聚合将 Mongodb shell 查询转换为 php

mongodb - 我可以在 MongoDB 聚合框架 $sort 上使用 2 个以上的字段吗?

mongodb - 具有 Match 的项目在 mongodb 中不起作用