2017-11-13 8 views
0

同じMongoDBコレクションにあるdiffドキュメントの配列間の値を比較する方法を見つけましたが、同じ配列内の要素をインデックスで比較するにはどうすればよいですか?は、ここで問題になっているエントリです:同じ文書内の配列の要素を比較するには?

{ "_id" : ObjectId("1"), "arr" : [ { "int" : 100 }, { "int" : 10 } ] } 

私は(もちろんここでは単純化)これらのエントリのトンでコレクションを持っている、と私は、各項目をチェックし、コレクションを照会したい場合、およびarr[0].int > arr[1].intそれらの文書を返す。 index 1の要素のパーセントがindex 0の要素からどのくらい離れているかを判断するロジックがさらに優れています。だからここに、例えば、mongoDocの要素が所定の値よりも大きい場合、照会するためindex 1 is 10 times less than index 0

以下の作品、この場合には:

db.collection.find({ "arr.0.int" : { $gt: 10 }}) 

私がこのプレイした - が、何も証明していません有用。 データセットが大容量であるため、パフォーマンスに関する考慮事項はすばらしくなります。

ありがとうございます!

+0

計算は「常に」高価です。あなたは "本当に"何をしようとしていますか?簡単なケースに答えることは本当に多くの答えではありません –

+0

ちょっと男 - それは本当に簡単なケースb/cに質問が本当にmongoの構文について、そしてこれがmongoで可能かどうかを考えます。 –

答えて

2

ここで基本的な場合は、単純に各インデックスで調べるために$redact$arrayElemAtで条件を適用することです:

db.collection.aggregate([ 
    { "$redact": { 
    "$cond": { 
     "if": { 
     "$gt": [ 
      { "$arrayElemAt": ["$arr.int", 0] }, 
      { "$arrayElemAt": ["$arr.int", 1] } 
     ] 
     }, 
     "then": "$$KEEP", 
     "else": "$$PRUNE" 
    } 
    }} 
]) 

これは"if"条件がある方法で$condを採用し、特殊なパイプラインステージであります"then"を受け取りました"$$KEEP"結果の文書、そうでなければ"else"私達は"$$PRUNE"それから結果。

これはネイティブ演算子を使用しており、計算に依存するこのようなクエリが得られるようになると「パフォーマンス」として機能します。でも、実際に.find()で使用することができ

db.collection.aggregate([ 
    { "$match": { 
    "$expr": { 
     "$gt": [ 
     { "$arrayElemAt": ["$arr.int", 0] }, 
     { "$arrayElemAt": ["$arr.int", 1] } 
     ] 
    } 
    }} 
]) 

db.collection.find({ 
    "$expr": { 
    "$gt": [ 
     { "$arrayElemAt": ["$arr.int", 0] }, 
     { "$arrayElemAt": ["$arr.int", 1] } 
    ] 
    } 
}) 

を介して、JavaScriptの評価を支えてきたのリリース以降のすべてのバージョン

のMongoDB 3.6

は少し短い $exprを使用して、この上の構文を使用できます $where

db.collection.find({ 
    "$where": "return this.arr[0].int > this.arr[1].int" 
}) 

しかし、これは各文書のJavaScript式の評価を必要とするため、ネイティブ演算子を使用する場合ほどの効果がありません。

また、あなたがあなたの「比」応答を得る唯一の方法は、実際に.find()クエリが行うことができない、結果が返され、「変更する」ことができます集約パイプラインを使用することです:

db.collection.aggregate([ 
    { "$redact": { 
    "$cond": { 
     "if": { 
     "$gt": [ 
      { "$arrayElemAt": ["$arr.int", 0] }, 
      { "$arrayElemAt": ["$arr.int", 1] } 
     ] 
     }, 
     "then": "$$KEEP", 
     "else": "$$PRUNE" 
    } 
    }}, 
    { "$addFields": { 
    "ratio": { 
     "$divide": [ 
     { "$arrayElemAt": ["$arr.int", 1] }, 
     { "$arrayElemAt": ["$arr.int", 0] } 
     ]   
    } 
    }} 
]) 

についての素晴らしいものは「ありませんコレクション内のすべてのドキュメントを実行し、条件に一致するかどうかを確認する以外の選択肢がないため、「条件としての計算」を行うことはできません。

これが「共通ロジック」の場合は、代わりにドキュメントに保存する方がよいでしょう。私。E:

{ "arr": [{ "int": 100 },{ "int": 10 }], "firstIsGreater": true } 

次に、あなたが実際には、効率的な方法で選択のためのインデックスを使用「することができます」。したがって、ドキュメント内のコンテンツを変更したときにこの条件を記述することは、アプリケーションロジックによって異なります。したがって、このような計算は必要ありません。

このようにモデル化して保存することができない場合は、どちらの形式でも計算が完了します。したがって、最初に計算された条件が必要と思われる理由を考えてみるのが一般的には良いです。

+0

あなたは紳士で、学者です!抜群の故障に感謝します! –

関連する問題