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

His*_*ako 4 mongodb meteor

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

{..., tags: ["a","b","c"], ...},
{..., tags: ["a","b","d"], ...},
{..., tags: ["b","c","e"], ...},
{..., tags: ["x","y","z"], ...},
....
Run Code Online (Sandbox Code Playgroud)

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

{..., tags: ["a","b","d"], ...},
{..., tags: ["a","b","c"], ...},
{..., tags: ["x","y","z"], ...}
Run Code Online (Sandbox Code Playgroud)

因为第一个doc有两个匹配,"a"而且"d",另外两个元素有一个匹配,"a""y".

目前我知道我可以$in用来匹配所有至少有一个匹配的$all文档,以获取每个标记匹配的所有文档,但这不会以某种方式削减它.如果需要,我也可以使用mongoDB的聚合框架.

需要的查询是什么样的?

Bat*_*eam 5

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

您需要使用聚合管道,可以写成如下:

  • Match 在标签阵列中具有至少一个匹配值的文档.
  • 我们将展开并处理tags数组,因此请在每个记录中保留tags数组的副本.
  • Unwindtags阵列.
  • 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.
])
Run Code Online (Sandbox Code Playgroud)

O/P:

{ "noOfMatches" : 2, "tags" : [ "a", "b", "d" ] }
{ "noOfMatches" : 1, "tags" : [ "x", "y", "z" ] }
{ "noOfMatches" : 1, "tags" : [ "a", "b", "c" ] }
Run Code Online (Sandbox Code Playgroud)