Java 查询MongoDB数组并使用最匹配的元素进行排序

Java 查询MongoDB数组并使用最匹配的元素进行排序,java,mongodb,Java,Mongodb,我需要你在以下情况下的专业知识 我有这样一个收藏: "array" : { "item" : 1, "1" : [100, 130, 255], } "array" : { "item" : 2, "1" " [0, 70, 120], } "array" : { "item" : 3, "1" : [100, 90, 140], } db.test.find(array.1 : {$in : [100, 80, 140]}); 我正在

我需要你在以下情况下的专业知识

我有这样一个收藏:

"array" : {
    "item" : 1,
    "1" : [100, 130, 255],
}

"array" : {
    "item" : 2,
    "1" " [0, 70, 120],
}

"array" : {
    "item" : 3,
    "1" : [100, 90, 140],

}
 db.test.find(array.1 : {$in : [100, 80, 140]});
我正在查询此集合,如下所示:

"array" : {
    "item" : 1,
    "1" : [100, 130, 255],
}

"array" : {
    "item" : 2,
    "1" " [0, 70, 120],
}

"array" : {
    "item" : 3,
    "1" : [100, 90, 140],

}
 db.test.find(array.1 : {$in : [100, 80, 140]});
这将返回项目编号1和3,因为它将提供的数组中的任何值与集合中的值相匹配。 不过,我想对这个数组进行排序,以获得具有更相似数字的结果。 结果应分别为第3项和第1项

但是,我可以获取结果并使用k-最近邻算法对数组进行排序。然而,处理庞大的数据集使得这非常不受欢迎(或者是吗?) MongoDB中是否有提供此功能的功能? 我用的是Java,有没有足够快的算法来实现这一点? 感谢您的帮助


谢谢。

您可以使用聚合框架来实现这一点,尽管这并不容易。问题在于操作符中没有作为聚合框架一部分的
$in。因此,必须通过编程匹配数组中的每个项,这会变得非常混乱。编辑:重新排序,使匹配项位于第一位,以防
$in
帮助您筛选出好的部分

db.test.aggregate(
  {$match:{"array.1":{$in:[100, 140,80]}}}, // filter to the ones that match
  {$unwind:"$array.1"}, // unwinds the array so we can match the items individually
  {$group: { // groups the array back, but adds a count for the number of matches
    _id:"$_id", 
    matches:{
      $sum:{
        $cond:[
          {$eq:["$array.1", 100]}, 
          1, 
          {$cond:[
            {$eq:["$array.1", 140]}, 
            1, 
            {$cond:[
              {$eq:["$array.1", 80]}, 
              1, 
              0
              ]
            }
            ]
          }
          ]
        }
      }, 
    item:{$first:"$array.item"}, 
    "1":{$push:"$array.1"}
    }
  }, 
  {$sort:{matches:-1}}, // sorts by the number of matches descending
  {$project:{matches:1, array:{item:"$item", 1:"$1"}}} // rebuilds the original structure
);
产出:

{
"result" : [
    {
        "_id" : ObjectId("50614c02162d92b4fbfa4448"),
        "matches" : 2,
        "array" : {
            "item" : 3,
            "1" : [
                100,
                90,
                140
            ]
        }
    },
    {
        "_id" : ObjectId("50614bb2162d92b4fbfa4446"),
        "matches" : 1,
        "array" : {
            "item" : 1,
            "1" : [
                100,
                130,
                255
            ]
        }
    }
],
"ok" : 1
}

如果最后将
匹配项
字段从
$project
中删除,则可以将该字段从结果中删除。

可以使用聚合框架执行此操作,尽管这并不容易。问题在于
操作符中没有作为聚合框架一部分的
$in。因此,必须通过编程匹配数组中的每个项,这会变得非常混乱。编辑:重新排序,使匹配项位于第一位,以防
$in
帮助您筛选出好的部分

db.test.aggregate(
  {$match:{"array.1":{$in:[100, 140,80]}}}, // filter to the ones that match
  {$unwind:"$array.1"}, // unwinds the array so we can match the items individually
  {$group: { // groups the array back, but adds a count for the number of matches
    _id:"$_id", 
    matches:{
      $sum:{
        $cond:[
          {$eq:["$array.1", 100]}, 
          1, 
          {$cond:[
            {$eq:["$array.1", 140]}, 
            1, 
            {$cond:[
              {$eq:["$array.1", 80]}, 
              1, 
              0
              ]
            }
            ]
          }
          ]
        }
      }, 
    item:{$first:"$array.item"}, 
    "1":{$push:"$array.1"}
    }
  }, 
  {$sort:{matches:-1}}, // sorts by the number of matches descending
  {$project:{matches:1, array:{item:"$item", 1:"$1"}}} // rebuilds the original structure
);
产出:

{
"result" : [
    {
        "_id" : ObjectId("50614c02162d92b4fbfa4448"),
        "matches" : 2,
        "array" : {
            "item" : 3,
            "1" : [
                100,
                90,
                140
            ]
        }
    },
    {
        "_id" : ObjectId("50614bb2162d92b4fbfa4446"),
        "matches" : 1,
        "array" : {
            "item" : 1,
            "1" : [
                100,
                130,
                255
            ]
        }
    }
],
"ok" : 1
}

如果在结尾时将
匹配项
字段从
$project
中删除,则可以将其从结果中删除。

嘿,谢谢@Stennie——也许我应该在
$cond
表达式中输入
$in
功能的请求;这会干净得多!似乎还没有对
$in
的请求,因此请在MongoDB问题跟踪器中添加一个。如果有人想观看或投票,请在MongoDB问题跟踪器中添加相关功能建议:。嘿,谢谢@Stennie——也许我应该在
$cond
表达式中请求
$in
功能;这会干净得多!在
中似乎还没有对
$的请求,因此请在MongoDB问题跟踪器中添加一个。如果有人想观看或投票,请在MongoDB问题跟踪器中添加相关功能建议:。