A.V*_*rno 2 arrays search mongodb
假设我想找到"tags"包含标签的字段的文档:"a", "b", "c".
如果我使用$and运算符,它将只返回"tags"包含所有三个标记的文档.
这种严格的搜索不是我想要的.如果我选择使用$or运算符,它将找到包含列表中至少一个标记的文档,但它不会尝试检查是否存在首先包含其中几个或全部的文档.
我想要做的是搜索包含"尽可能多的标签,但至少有一个"的文档,或者换句话说,找到包含至少一个标签的所有文档,但首先显示最匹配的文档.我知道我可以通过一系列查询来做到这一点(例如,使用$and查询然后$or),但如果有更多的2标签,我将不得不使用不同的标签组合进行大量查询以获得良好的结果.
您可以汇总结果如下:
$match所有至少1匹配的文件.$project一个变量weight,它保存文档包含的匹配标记数.要查找匹配的标记,请使用$setIntersection运算符.$sort 按重量按降序排列.$project 必填字段.样本数据:
db.t.insert([{"tags":["a","b","c"]},
{"tags":["a"]},
{"tags":["a","b"]},
{"tags":["a","b","c","d"]}])
Run Code Online (Sandbox Code Playgroud)
搜索条件:
var search = ["a","b"];
Run Code Online (Sandbox Code Playgroud)
码:
db.t.aggregate([
{$match:{"tags":{$in:search}}},
{$project:{"weight":{$size:{$setIntersection:["$tags",search]}},
"tags":"$tags"}},
{$sort:{"weight":-1}},
{$project:{"tags":1}}
])
Run Code Online (Sandbox Code Playgroud)
O/P:
{
"_id" : ObjectId("54e23b74c6185de718484948"),
"tags" : [
"a",
"b",
"c"
]
}
{ "_id" : ObjectId("54e23b74c6185de71848494a"), "tags" : [ "a", "b" ] }
{
"_id" : ObjectId("54e23b74c6185de71848494b"),
"tags" : [
"a",
"b",
"c",
"d"
]
}
{ "_id" : ObjectId("54e23b74c6185de718484949"), "tags" : [ "a" ] }
Run Code Online (Sandbox Code Playgroud)