Mongo按数组中的匹配计数排序 [英] Mongo Sort by Count of Matches in Array

查看:56
本文介绍了Mongo按数组中的匹配计数排序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

可以说我的测试数据是

db.multiArr.insert({"ID" : "fruit1","Keys" : ["apple", "orange", "banana"]})
db.multiArr.insert({"ID" : "fruit2","Keys" : ["apple", "carrot", "banana"]})

要像胡萝卜一样得到单个水果

to get individual fruit like carrot i do

db.multiArr.find({'Keys':{$in:['carrot']}})

当我进行橙色"和香蕉"查询时,我既看到了水果记录,又看到了水果记录

when i do an or query for orange and banana, i see both the records fruit1 and then fruit2

db.multiArr.find({ $or: [{'Keys':{$in:['carrot']}}, {'Keys':{$in:['banana']}}]})

输出结果应该是fruit2,然后是fruit1,因为fruit2既有胡萝卜又有香蕉

Result of the output should be fruit2 and then fruit1, because fruit2 has both carrot and banana

推荐答案

要真正首先回答这个问题,您需要计算"与给定条件的匹配数,以便对结果进行排序",并以首选项显示最匹配的结果返回.

To actually answer this first, you need to "calculate" the number of matches to the given condition in order to "sort" the results to return with the preference to the most matches on top.

为此,您需要一个聚合框架,该框架用于在MongoDB中计算"和操纵"数据:

For this you need the aggregation framework, which is what you use for "calculation" and "manipulation" of data in 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上,您可以执行更长的格式:

On an MongoDB older than version 3, then you can do the longer form:

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 either case the function here is to first match the possible documents to the conditions by providing a "list" of arguments with $in. Once the results are obtained you want to "count" the number of matching elements in the array to the "list" of possible values provided.

现代形式的 $setIntersection 运算符将两个列表"返回一个仅包含唯一"匹配成员的新数组.由于我们想知道那有多少个匹配项,因此我们只需返回 $size .

In the modern form the $setIntersection operator compares the two "lists" returning a new array that only contains the "unique" matching members. Since we want to know how many matches that was, we simply return the $size of that list.

在旧版本中,您可以使用 $unwind ,以便对其执行操作,因为较早的版本缺少无需更改即可使用数组的较新的运算符.然后,该过程将分别查看每个值,以及 $or 匹配可能的值,然后 $cond 三元返回一个值1 $sum 累加器,否则0.最终结果是与现代版本相同的匹配数".

In older versions, you pull apart the document array with $unwind in order to perform operations on it since older versions lacked the newer operators that worked with arrays without alteration. The process then looks at each value individually and if either expression in $or matches the possible values then the $cond ternary returns a value of 1 to the $sum accumulator, otherwise 0. The net result is the same "count of matches" as shown for the modern version.

最后一件事就是简单地 $sort 结果基于返回的匹配数",因此最多匹配项位于顶部".这是降序",因此您提供-1来表明这一点.

The final thing is simply to $sort the results based on the "count of matches" that was returned so the most matches is on "top". This is is "descending order" and therefore you supply the -1 to indicate that.

您误解了有关初学者的MongoDB查询的几件事. $in运算符实际上用于这样的参数列表":

You are misunderstanding a couple of things about MongoDB queries for starters. The $in operator is actually intended for a "list" of arguments like this:

{ "Keys": { "$in": [ "carrot", "banana" ] } }

从本质上讲,这是在属性键"中匹配胡萝卜" 香蕉"的简写方式" .甚至可以这样写成很长的格式:

Which is essentially the shorthand way of saying "Match either 'carrot' or 'banana' in the property 'Keys'". And could even be written in long form like this:

{ "$or": [{ "Keys": "carrot" }, { "Keys": "banana" }] }

如果这是一个单一"匹配条件,那么您真的应该带给您,然后您只需提供要与该属性匹配的值即可:

Which really should lead you to if it were a "singular" match condition, then you simply supply the value to match to the property:

{ "Keys": "carrot" }

因此,这应该涵盖您使用 $in 匹配作为文档内数组的属性.相反,反向"情况是预期的用法,在这种情况下,您将提供参数列表"以匹配给定的属性,该属性可以是数组,也可以是单个值.

So that should cover the misconception that you use $in to match a property that is an array within a document. Rather the "reverse" case is the intended usage where instead you supply a "list of arguments" to match a given property, be that property an array or just a single value.

MongoDB查询引擎在相等或类似操作中不区分单个值或值数组.

The MongoDB query engine makes no distinction between a single value or an array of values in an equality or similar operation.

这篇关于Mongo按数组中的匹配计数排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆