2

我正在尝试使用新的 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"] 看起来像:

{
  $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% 的方式。

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

4

1 回答 1

4

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

{
  $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的 (相当于 a .find())使用适当的索引。

于 2012-09-20T15:08:27.347 回答