MongoDB:查找与大多数标签匹配的文档

时间:2014-12-06 00:15:11

标签: mongodb meteor

在我的流星应用程序中,我有大量文档,每个文档都有一个字段tags,基本上是这样的:

{..., tags: ["a","b","c"], ...},
{..., tags: ["a","b","d"], ...},
{..., tags: ["b","c","e"], ...},
{..., tags: ["x","y","z"], ...},
....

现在我想在服务器上查询一些标签,例如:["a","d","y"]并获得与至少一个标签匹配的所有结果,以及匹配标签数量排序的结果集。因此,在示例集中,结果应为:

{..., tags: ["a","b","d"], ...},
{..., tags: ["a","b","c"], ...},
{..., tags: ["x","y","z"], ...}

因为第一个文档有两个匹配项"a""d",其他两个元素有一个匹配项"a""y"

目前,我知道我可以使用$in来匹配所有至少有一个匹配的文档$all,以获取每个标记匹配的所有文档,但这并不能以某种方式将其删除。如果需要,我也可以使用mongoDB的聚合框架。

所需查询的外观如何?

1 个答案:

答案 0 :(得分:5)

  

如果需要,我也可以使用mongoDB的聚合框架。

您需要使用聚合管道,可以按如下方式编写:

  • Match在标签中至少有一个匹配值的文档 阵列。
  • 我们将展开并处理标签数组,因此请保留一份副本 每条记录中的标签数组。
  • Unwind tags数组。
  • Match输入数组中包含其标记值的记录。
  • Group位于_id字段,并计算匹配的文档数。
  • Sort这些群组根据匹配数量而定。
  • project必填字段以及我们创建的原始代码数组副本。

代码:

var inp = ["a","d","y"];

db.collection.aggregate([
{$match:{"tags":{$in:inp}}},
{$project:{"tagsCopy":"$tags","tags":1}},
{$unwind:"$tags"},
{$match:{tags:{$in:inp}}},
{$group:{"_id":"$_id","noOfMatches":{$sum:1},"tags":{$first:"$tagsCopy"}}},
{$sort:{noOfMatches:-1}},
{$project:{"_id":0,"noOfMatches":1,tags:1}} //remove noOfMatches and 
                                            //add other required 
                                            //fields which are necessary.
])

O / P:

{ "noOfMatches" : 2, "tags" : [ "a", "b", "d" ] }
{ "noOfMatches" : 1, "tags" : [ "x", "y", "z" ] }
{ "noOfMatches" : 1, "tags" : [ "a", "b", "c" ] }