让我说我的测试数据是
db.multiArr.insert({"ID" : "fruit1","Keys" : ["apple", "orange", "banana"]})
db.multiArr.insert({"ID" : "fruit2","Keys" : ["apple", "carrot", "banana"]})
获得像胡萝卜一样的个人水果
db.multiArr.find({'Keys':{$in:['carrot']}})
当我对橙色和香蕉进行查询或查询时,我会看到记录fruit1然后是fruit2
db.multiArr.find({ $or: [{'Keys':{$in:['carrot']}}, {'Keys':{$in:['banana']}}]})
输出的结果应该是fruit2然后是fruit1,因为fruit2有胡萝卜和香蕉
答案 0 :(得分:5)
要先实际回答这个问题,你需要"计算"给定条件的匹配数,以便排序"排序"结果以优先选择返回顶部的大多数匹配。
为此,您需要聚合框架,这是您用于"计算"和"操纵" MongoDB中的数据:
db.multiArr.aggregate([
{ "$match": { "Keys": { "$in": [ "carrot", "banana" ] } } },
{ "$project": {
"ID": 1,
"Keys": 1,
"order": {
"$size": {
"$setIntersection": [ ["carrot", "banana"], "$Keys" ]
}
}
}},
{ "$sort": { "order": -1 } }
])
在版本低于3的MongoDB上,您可以使用更长的格式:
db.multiArr.aggregate([
{ "$match": { "Keys": { "$in": [ "carrot", "banana" ] } } },
{ "$unwind": "$Keys" },
{ "$group": {
"_id": "$_id",
"ID": { "$first": "$ID" },
"Keys": { "$push": "$Keys" },
"order": {
"$sum": {
{ "$cond": [
{ "$or": [
{ "$eq": [ "$Keys", "carrot" ] },
{ "$eq": [ "$Keys", "banana" ] }
]},
1,
0
]}
}
}
}},
{ "$sort": { "order": -1 } }
])
在任何一种情况下,此处的功能是首先通过提供"列表"将可能的文档与条件匹配。与$in
的争论。一旦获得结果,您希望"计算"数组中匹配元素的数量为" list"提供的可能值。
在现代形式中,$setIntersection
运算符比较两个"列表"返回一个只包含" unique"的新数组。匹配成员。由于我们想知道有多少匹配,我们只需返回该列表的$size
。
在旧版本中,您将文档数组与$unwind
分开,以便对其执行操作,因为旧版本缺少使用数组而无需更改的较新运算符。然后,该流程会单独查看每个值,如果$or
中的任一表达式与可能的值匹配,则$cond
三元组会将1
的值返回到$sum
累加器,否则{ {1}}。最终结果是相同的"匹配数"如现代版本所示。
最后一件事就是$sort
结果基于"匹配数"返回的是最匹配的是" top"。这是"降序"因此,您提供0
来表示。
你误解了关于初学者的MongoDB查询的一些事情。 -1
运算符实际上是用于"列表"像这样的论点:
$in
这实际上是简单的说法"匹配胡萝卜' 或' banana'在物业' Keys'" 。甚至可以用这样的长篇形式写出来:
{ "Keys": { "$in": [ "carrot", "banana" ] } }
如果它是一个"单数"那真的应该引导你。匹配条件,然后您只需提供与属性匹配的值:
{ "$or": [{ "Keys": "carrot" }, { "Keys": "banana" }] }
这应该涵盖您使用$in
来匹配文档中数组的属性的误解。相反,"反向" case是预期的用法,而你提供一个"参数列表"匹配给定的属性,该属性是数组或只是一个值。
MongoDB查询引擎在相等或类似操作中不区分单个值或值数组。