2016-09-16 6 views
2

は例がこのようなコレクション内の1つのエントリで、次のコレクションの定義と仮定:特定の列挙を返すにmongoはフィールド内の配列だけを返す方法はありますか?

enumeration : { 
    name: 'enumeration-1' 
    elements: [ 
     { 
      value: 'value-1' 
      tags: ['tag-1', 'tag-2'] 
     }, 
     { 
      value: 'value-2', 
      tags: ['tag-2', 'tag'-3'] 
     }, 
     { 
      value: 'value-3' 
      tags: ['tag-3', 'tag-4'] 
     } 
    ] 
} 

を非常に簡単です:

db.enumerations.find({ name: 'enumeration-1' }) 

はしかし、私はリターンにそのクエリを増補必要各要素がタグのリストに少なくとも1つのタグを持つ要素のみ。次のパラメータを考慮してください。

1. name: 'enumeration-1' 
2. tags: ['tag-1', 'tag-4'] 

私はあることを出力する必要があります。

['value-1', 'value-3'] 

つまり、私は内に含まれている指定されたタグの1つ以上を有する要素の値のみを必要とします列挙型1.可能な場合、クエリはどのように見えるでしょうか?完全な要素を返すこともうまくいきます。私はMongo 2.6.9を使用しています。

+0

のようになります。しかし、私はあなたの最初の例を意味しました。 – predhme

答えて

1

あなたが集約フレームワークを使用することができます。 findクエリの代替は$elemMatchまたは$projectionです。どちらも、最初の一致する要素を配列に返すだけで、すべての値が必要なので、それらはあなたのケースでは機能しません。 。配列値でフィルタリングする必要がありますが、別のものを投影する必要があります。

しかし、ここでは集約フレームワークでどのように機能するかについて説明します(必要に応じて、結果を一意にするなど、最終的にすべての処理を行うことができます)。この

db.enumerations.aggregate(
{$match:{"enumeration.name":"enum-1"}}, 
{$unwind:"$enumeration.elements"}, 
{$unwind:"$enumeration.elements.tags"}, 
{$match:{"enumeration.elements.tags":{$in:["tag-1","tag-4"]}}}, 
{$project:{"enumeration.elements.value":1}}) 
0

これがうまくいくかどうかはわかりませんが(メモリから)、配列検索のために$ elemMatchを見てから、見つかる2番目のオプションの引数(投影用)を見ているようです。

db.enumerations.find({ name: 'enumeration-1', elements : {$elemMatch : { $in : ['tag-1', 'tag-4']}}}, {_id:0, 'elements.value':1}) 
+0

私が信じているこの質問は近いですが、結果は返されません。私は 'tags'属性にqualiferが存在しないので、それが正しいかどうか疑問に思います。私はこのクエリーを 'db.enumerations.find({name: 'enumeration-1'、要素:{$ elemMatch:{tags:{$ elemMatch:{$ in:{['tags-1'、 'タグ-4 ']}}}}}}) '。しかし、それはすべての値を返す(期待されない値-2も含む)。 – predhme

1

あなたが剪定された要素の配列を生成するためにハック(汚い1)としてset operatorsを使用して、次の集計操作を実行できます。

var query = { 
    "name": "enumeration-1", 
    "tags": ["tag-1", "tag-4"] 
}; 

db.enumerations.aggregate([ 
    { "$match": { "name": query.name } }, 
    { 
     "$project": { 
      "name": 1, 
      "elements": { 
       "$setDifference": [ 
        { 
         "$map": { 
          "input": "$elements", 
          "as": "el", 
          "in": { 
           "$cond": [ 
            {           
             "$setEquals": [             
              { 
               "$setIntersection": [ 
                "$$el.tags", query.tags 
               ] 
              }, 
              [] 
             ]           
            },          
            false, 
            "$$el" 
           ] 
          } 
         } 
        }, 
        [false] 
       ] 
      } 
     } 
    } 
]) 
+0

@predhmeなぜこの回答を受け入れなかったのか教えてください。これは私に将来的に私の答えをより明確にするための建設的な批判を与えるでしょう。 – chridam

+1

私がこの回答を最初に受け入れたとき、私はMongoコンソールの中でテストしました。しかし、クエリをJongo(私たちのmongoフレームワーク)に置くと、明示的な理由がないため、クエリが適切に解析されません。私はドキュメントを検索して何度も試しましたが、Jongoから実行したときにクエリが失敗しました。私が使用しているjavaドライバは、Mongo verisonにマッチする2.6.9です。私はJongo 1.2を使用しています。 – predhme

+0

明確化のおかげで:) – chridam

0
db.enumerations.aggregate([ 
    { $match: {"name":"enumeration-1"} }, 
    { $unwind: "$elements" }, 
    { $unwind: "$elements.tags" }, 
    { $match: {"elements.tags": { $in:["tag-1","tag-4"] } }}, 
    { $group : { _id : null, values: { $push: "$elements.value" } } }, 
    { $project: {"_id":0, values:1}} 
]) 

出力は、私はそれに応じて質問を修正します

{ 
    "values" : [ "value-1", "value-3"] 
} 
関連する問題