2017-07-31 18 views
1

次のコレクションを考えてみましょう。親ドキュメントの値はであり、フィールドには同じフィールドのamountと同じ値が埋め込まれています。mongoDBを使用して埋め込みドキュメントを親フィールドと比較

{ 
"_id" : ObjectId("5975ce5f05563b6303924914"), 
"amount" : 100000, 
"offers" : [ 
    { 
     "amount": 100000 
    } 
] 

}

親と同じ量の少なくとも1つの埋め込み文書offerを持っているすべてのオブジェクトを一致させる方法はありますか?

Iの例のクエリの場合、この、それだけで正常に動作します:

find({ offers: { $elemMatch: { loan_amount: 100000 } } }) 
しかし、私は、私が組み立てしようとしている実際のクエリで実際の値 100000を知らない、私が使用する必要があります親伝票額項目の変数。このようなもの。

find({ offers: { $elemMatch: { loan_amount: "parent.loan_amount" } } }) 

ありがとうございます。私は$eqまたは$elemMatchでこれを行い、集約を避けることを望んでいましたが、おそらくそれは不可能です。

ありがとうございます!

答えて

2

標準クエリでは、ドキュメントの値を「比較」できません。

db.collection.aggregate([ 
    { "$redact": { 
    "$cond": { 
     "if": { 
     "$gt": [ 
      { "$size": { 
      "$filter": { 
       "input": "$offers", 
       "as": "o", 
       "cond": { "$eq": [ "$$o.amount", "$amount" ] } 
      } 
      }}, 
      0 
     ] 
     }, 
     "then": "$$KEEP", 
     "else": "$$PRUNE" 
    } 
    }} 
]) 

をここでは、アレイ内のものにした、親ドキュメント内に"amount"の値を比較する$filterを使用します。これは実際にあなたが.aggregate()$redactを使用しないものです。少なくとも1つが「等しければ」"$$KEEP"、それ以外の場合は"$$PRUNE"

最新のバージョンでは、$indexOfArrayを使用してこれを短縮することができます。

db.collection.aggregate([ 
    { "$redact": { 
    "$cond": { 
     "if": { 
     "$ne": [ 
      { "$indexOfArray": [ "$offers.amount", "$amount" ] }, 
      -1 
     ] 
     }, 
     "then": "$$KEEP", 
     "else": "$$PRUNE" 
    } 
    }} 
]) 

あなたは、実際には、「一致する配列の要素(複数可)」だけでなく、あなたが投影で$filterを追加したい場合:

db.collection.aggregate([ 
    { "$redact": { 
    "$cond": { 
     "if": { 
     "$gt": [ 
      { "$size": { 
      "$filter": { 
       "input": "$offers", 
       "as": "o", 
       "cond": { "$eq": [ "$$o.amount", "$amount" ] } 
      } 
      }}, 
      0 
     ] 
     }, 
     "then": "$$KEEP", 
     "else": "$$PRUNE" 
    } 
    }}, 
    { "$project": { 
    "amount": 1, 
    "offers": { 
     "$filter": { 
     "input": "$offers", 
     "as": "o", 
     "cond": { "$eq": [ "$$o.amount", "$amount" ] } 
     } 
    } 
    }} 
]) 

をしかし、主な原則は、「削減することはもちろんですに戻された文書数はで、実際には「最初の」優先度として条件に一致しています。それ以外の場合は、不要な計算や作業をしているだけで、時間とリソースを費やしているので、後で破棄する可能性があります。

最初に「フィルタ」、最初に「再整形」を優先します。

+0

オファーの文書に他の文書を参照して独自のコレクションがあると、それほど簡単ではないでしょうか。この集約はたくさんの仕事のように思えますが、私はパフォーマンスを重視しています。オファー文書を自分のコレクションに入れて他の文書のIDを参照する方が良いでしょうか? –

+0

@StefanKonno別のコレクションに物を入れることはパフォーマンスが賢明です**悪い**です。費用はかかりますし、大変です。このため、最初にMongoDBを使用する必要があります。あるフィールドを他のフィールドと比較する「簡単な」方法はありません。どの方法にもコストがあり、これはリレーショナルデータベースにも当てはまります。 –

+0

もう一度おねがいします。試してみます。私はあなたの努力に感謝し、良い一日を! –

関連する問題