0

次の状況について、あなたの専門知識が必要です。

私はそのようなコレクションを持っています:

"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を使用していますが、これを十分に速く達成するためのアルゴリズムはありますか? どんな助けでも大歓迎です。

ありがとう。

4

1 に答える 1

5

簡単ではありませんが、集約フレームワークを使用してこれを行うことができます。$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
}

matches最後にフィールドを除外すると、結果からフィールドを除外できます$project

于 2012-09-25T07:08:40.573 に答える