2017-07-07 10 views
1

私は実行時に作成されたメモリ内に配列Aをもち、mongoデータベースに保存された別の配列Bを持っています。どのようにしてBにないAからすべての要素を効率的に得ることができますか?配列を比較して差分を返す

mongodbに格納されている配列は、実行時に作成された配列よりも数桁大きいと考えられます。そのため、mongoから完全な配列を取得して結果を計算するのは効率的ではないでしょう私が望む結果を計算できるmongoのクエリ操作は見つかりませんでした。

$ninオペレータは、私が何をしたいの反対をないことに注意してください、すなわち、それはAに

例ではありませんBから要素を取得します。実行時に私のapplictionで作成

アレイA、は、[2, 3, 4]です。

mongodbに格納された配列Bは、[1, 3, 5, 6, 7, 10]です。

私が期待する結果は[2, 4]です。

答えて

3

応答でドキュメントを「変更する」唯一のものは、.aggregate().mapReduce()です(前者がより良いオプションです)。

この場合、 "sets"を比較し、その2つの間に "difference"を返す$setDifferenceを求めています。だからあなたの配列で文書を表す

db.collection.insert({ "b": [1, 3, 5, 6, 7, 10] }) 

ラン集約:

db.collection.aggregate([{ "$project": { "c": { "$setDifference": [ [2,3,4], "$b" ] } } }]) 

返します

{ "_id" : ObjectId("596005eace45be96e2cb221b"), "c" : [ 2, 4 ] } 

をあなたの代わりに "セット" を望んでいない場合[2,3,4,4]のような配列を指定したい場合は$filterと0123と比較できます代わりに、あなたは少なくともMongoDBの3.4を持っている場合:

db.collection.aggregate([ 
    { "$project": { 
    "c": { 
     "$filter": { 
     "input": [2,3,4,4], 
     "as": "a", 
     "cond": { 
      "$not": { "$in": [ "$$a", "$b" ] } 
     } 
     } 
    } 
    }} 
]) 

またはそれ以前のバージョンで$filter$anyElementTrueと:

db.collection.aggregate([ 
    { "$project": { 
    "c": { 
     "$filter": { 
     "input": [2,3,4,4], 
     "as": "a", 
     "cond": { 
      "$not": { 
      "$anyElementTrue": { 
       "$map": { 
       "input": "$b", 
       "as": "b", 
       "in": { 
        "$eq": [ "$$a", "$$b" ]  
       } 
       }  
      } 
      } 
     }  
     } 
    }  
    }} 
]) 
両方が戻ってくる

:もちろんです

{ "_id" : ObjectId("596005eace45be96e2cb221b"), "c" : [ 2, 4, 4 ] } 

4が入力「2回」として提供されたので「セットではない」ため、「2回」も返されます。

関連する問題