返回数组比较之间的匹配百分比

时间:2017-08-01 16:50:35

标签: mongodb mongodb-query aggregation-framework bigdata

我有一个包含大量数据的mongodb存储库,我需要在给定输入的情况下搜索和分类数据。

我计划让服务器工作来处理请求并给出响应,但我不确定使用哪种算法,bigdata工具甚至mongodb命令。

这是我需要做的一个例子。

我有这个数据库:

[
    {
        id: 1,
        Colors: ["Green","Red","Blue","Yellow"]
    },
    {
        id: 2,
        Colors: ["Green","Red","Blue"]
    },
    {
        id: 3,
        Colors: ["Green","Red"]
    },
    {
        id: 4,
        Colors: ["Green"]
    }
]

然后我有了这个输入

String x = "Green Red" 

或类似

的JSON
 { Colors: ["Green","Red"]}

然后它将返回与此输入匹配的数据:

[
    {
        id: 4,
        Colors: ["Green"],
        Matches: 100%
    }
    {
        id: 3,
        Colors: ["Green","Red"],
        Matches: 100%
    },
    {
        id: 2,
        Colors: ["Green","Red","Blue"],
        Matches: 66%
    },
    {
        id: 1
        Colors: ["Green","Red","Blue","Yellow"],
        Matches: 50%
    }
]

1 个答案:

答案 0 :(得分:1)

简单来说,您希望通过源输入中的正匹配来$filter数组,然后将生成的$size与原始匹配进行比较。版本之间的技术略有不同,但基本上是:

db.getCollection('junk').aggregate([
  { "$addFields": {
    "Matches": {
      "$trunc": {
        "$multiply": [
          { "$divide": [
            { "$size": {
              "$filter": {
                "input": "$Colors",
                "as": "c",
                "cond": { "$in": [ "$$c", ["Green","Red"] ] }
              }
            }}, 
            { "$size": "$Colors" }
          ]},
          100
        ]
      }
    }
  }}
])

只要比较值和数组都包含“唯一”元素,您就可以使用$setIntersection而不是使用$filter

db.getCollection('junk').aggregate([
  { "$addFields": {
    "Matches": {
      "$trunc": {
        "$multiply": [
          { "$divide": [
            { "$size": {
                "$setIntersection": [ "$Colors", ["Green", "Red"] ] 
            }}, 
            { "$size": "$Colors" }
          ]},
          100
        ]
      }
    }
  }}
])

如果您没有$trunc$floor,则只需使用$mod$subtract进行数学运算即可丢弃余数:

db.getCollection('junk').aggregate([
  { "$project": {
    "id": 1,
    "Colors": 1,
    "Matches": {
      "$let": {
        "vars": {
          "perc": {
            "$multiply": [
              { "$divide": [
                { "$size": {
                    "$setIntersection": [ "$Colors", ["Green", "Red"] ] 
                }}, 
                { "$size": "$Colors" }
              ]},
              100
            ]
          }
        },
        "in": {
          "$subtract": [ "$$perc", { "$mod": [ "$$perc", 1 ] } ]      
        }
      }
    }
  }}
])

虽然一般保持相同的原则。

  

“匹配数除以数组总长度等于匹配百分比”