2016-04-14 7 views
0

サブ文書内を検索しようとしています。これは私の文書の私の構造である:MongoDB - サブ文書を検索する

{ 
    _id: <ObjectID>, 
    email: ‘[email protected]’, 
    password: ‘12345’, 
    images: [ 
     { 
      title: ‘Broken Hand’, 
      description: ‘Here is a full description’, 
      comments: [ 
       { 
        comment: ‘Looks painful’, 
       } 
      ], 
      tags: [‘hand’, ‘broken’] 
     } 
    ] 
} 

と私は特定のタグを持つすべてのユーザーからのすべての画像を見つけることができるようにしたいが、私は使用していたクエリは、それはそれで見つかった最初の画像を返しますタグ:

誰かがどのようにすべての画像を取得することができますか?

+0

あなたのelemの一致は、フィルタセクションの代わりにプロジェクトセクションにあるようです(しかし、間違いかもしれません)。 'db.site_users.find({'images.tags':" broken "、{images:{$ elemMatch:{'tags': 'broken'}}}、{images:1})pretty()' ? –

答えて

0

あなたはそのためaggregation frameworkを使用することができます。

db.site_users.aggregate([ 
    {$unwind: "$images"}, 
    {$match:{ 
     "images.tags": "broken" 
    }} 
]) 
0

それが文書に一致するようクエリは良いですが、「投影」はあなたが.find()で何ができるかの範囲外で、あなたが必要.aggregate()と、 "画像"項目を配列から削除しないように注意し、一致しない "タグ"のみを削除しました。限り、「画像」などのコンテンツがための「ユニーク」で、$mapもMongoDBを2.6と互換性のある$setDifferenceを使用して、おそらく

db.site_users.aggregate([ 
    { "$match": { "images.tags": "broken" }}, 
    { "$project": { 
     "email": 1, 
     "password": 1, 
     "images": { 
      "$filter": { 
       "input": "$images", 
       "as": "image", 
       "cond": { 
        "$setIsSubSet": [["broken"], "$$image.tags"] 
       } 
      } 
     } 
    }} 
]) 

または:

理想的には、あなたは​​$projectの内側を使用してのMongoDB 3.2でこれを行います各エントリ。これは、「設定」の操作にある、「セット」は「ユニーク」された:

db.site_users.aggregate([ 
    { "$match": { "images.tags": "broken" }}, 
    { "$project": { 
     "email": 1, 
     "password": 1, 
     "images": { 
      "$setDifference": [ 
       { "$map": { 
        "input": "$images", 
        "as": "image", 
        "in": { 
         "$cond": { 
          "if": { "$setIsSubSet": [["broken"], "$$image.tags" ] }, 
          "then": "$$image", 
          "else": false 
         } 
        } 
       }}, 
       [false] 
      ] 
     } 
    }} 
]) 

それはMongoDBの以前のバージョンで行うことができますが、おそらく最高の原因に処理$unwindのコストを回避することができます配列:

db.site_users.aggregate([ 
    { "$match": { "images.tags": "broken" }}, 
    { "$unwind": "$images" }, 
    { "$match": { "images.tags": "broken" }}, 
    { "$group": { 
     "_id": "$_id", 
     "email": { "$first": "$email" }, 
     "password": { "$first": "$password" }, 
     "images": { "$push": "$images" } 
    }}  
]) 

あなたが何かを「集約」されていない。この目的のために$unwindを使用することにかなりのコストが通常ありますので、あなたが他の実用的なアプローチが利用可能な最新のバージョンを持っていない場合は、その後、それはですサーバ上ではなくクライアントコード内で配列コンテンツ自体を「フィルタリング」することが最も良い方法です。

したがって、一致しない項目を削除する順番で配列のエントリが「大幅に」削減される場合は、$unwindにしてください。さもなければ、処理コストはデータ転送のネットワークコストよりも大きい可能性があり、利益は無効になります。

最新バージョンをお持ちでない場合は、最新版を入手してください。この機能は、実用的で実用的なものとは全く異なるものになります。

関連する問題