2013-06-25 17 views
32

私はanother質問のコメントとしてこれを尋ねました。また、questionをmongodb-userに投稿しました。これまでの回答はないので、私は別の質問をすることに頼っています。MongoDBのネストされた配列クエリ

documentation状態:

フィールドが配列を保持している場合は、オペレータで$は、そのフィールド指定された配列の値と一致した少なくとも一つの 要素を含む配列を保持している 文書を選択し、 (例えば、 など)

私が使用している:

mongod --version: 
db version v2.2.2, pdfile version 4.5 
Thu May 30 12:19:12 git version: d1b43b61a5308c4ad0679d34b262c5af9d664267 

mongo --version: 
MongoDB shell version: 2.0.4 
MongoDBのシェルで

db.nested.insert({'level1': {'level2': [['item00', 'item01'], ['item10', 'item11']]}}) 

ここではマニュアルに従って動作するはずのクエリ、それらが生み出す結果のリストです:

なぜこの仕事をしますか?

> db.nested.findOne({'level1.level2.0': 'item00'}) 
null 

なぜ$ allが必要なのですか?

> db.nested.findOne({'level1.level2.0': {'$all': ['item00']}}) 
{ 
    "_id" : ObjectId("51a7a4c0909dfd8872f52ed7"), 
    "level1" : { 
     "level2" : [ 
      [ 
       "item00", 
       "item01" 
      ], 
      [ 
       "item10", 
       "item11" 
      ] 
     ] 
    } 
} 

次のうち少なくとも1つは正常に動作するはずです。

> db.nested.findOne({'level1.level2.0': {'$in': ['item00']}}) 
null 

> db.nested.findOne({'level1.level2': {'$in': ['item00']}}) 
null 

クエリ構文が広告として機能しない場合、MongoDBを放棄することを検討しています。

ありがとうございます!

答えて

6

ネストされたelemMatchを使用して、配列内のネストされたレベルを検索します。

詳細here

4

簡単な答え:$ inは単一値フィールド用で、$ allは配列用です。

まず、level1.level2.0は配列を保持しており、1つの値と比較しようとしているため、db.nested.findOne({'level1.level2.0': 'item00'})は機能しません。

今のところ、db.nested.findOne({'level1.level2.0': {'$in': ['item00']}})は、同様の理由により動作しません。 $ inは、配列内の複数の値(クエリで指定された値)を持つ単一の値(配列を持つ)とフィールドを比較するためのものです。 $ inは言っています:この配列に値が入っているこのフィールドを持つドキュメントを教えてください。

$これはいくつかの値を持つこのフィールドを持つドキュメントを教えてください。クエリのこの配列のすべての値がそのフィールドに含まれています。

が得るが、ドキュメントはそれぞれの言うことを見て難しいかもしれません(編集済み):

を$すべてはフィールドが配列を保持しているドキュメントを選択し、含まれるすべての要素(e.g. <value>, <value1>, etc.)で配列。

$ではフィールドの値が指定された配列e.g. <value1>, <value2>, etc.)の任意の値に等しい文書

を選択し、いくつかのクエリを実行した後、それは

+0

あなたはお返事をお待ちしておりますが、残念ながら、あなたの回答はどれも正しいものではありません。マニュアルの「読み込み」ページで、「次の操作は、アレイフィールドに含まれるすべての文書にカーソルを戻します。このフィールドには、「UNIX」という要素が含まれています。 $ inは配列を含むフィールドで動作するはずです。最後に、 "$ allが働いているため..."という記述は間違っています:フィールド内のすべての値がクエリに存在する必要はなく、クエリのすべての値がドキュメントのフィールドに存在する必要があります。 – dgorur

+0

「$が原因で作業しています...」の修正をありがとうございます。だからあなたは$ inが配列のために働くべきだと言っています。今私は興味をそそられる。私はいくつかの実験をして、私が調べるかどうかを見ます。あなたはここで非常に興味深い質問をしています! – AntonioOtero

+0

私は別の答えに私の発見を入れて、私はそれがあなたに役立つことを願っています。 – AntonioOtero

29

を役に立てば幸い、私はという結論に達しました配列の配列では$ inが機能しません。

代わりに$elemMatchを使用することができますが、動作しますが、MongoDBのドキュメントで警告が表示されないというのは残念です。文字列の配列であり、このクエリは完璧に動作し、フィールド「アイテム」という

{ 
     "_id": "51cb12857124a215940cf2d4", 
     "level1": [ 
     [ 
      "item00", 
      "item01" 
     ], 
     [ 
      "item10", 
      "item11" 
     ] 
     ], 
     "items": [ 
     "item20", 
     "item21" 
     ] 
} 

がお知らせ::私は、この文書作成

db.nested.findOne({"items":{"$in":["item20"]} }) 

を、「level1.0」もあります文字列の配列ですが、唯一の違いは別の配列の内側にあることです。このクエリは動作しますが、ではないはずです。

db.nested.findOne({"level1.0":{"$in":["item00"]} }) 

結果は$ elemMatchを使用している取得する唯一の方法:

db.nested.findOne({"level1":{"$elemMatch":{"$in":['item00']}} }) 

ので$elemMatchは、問題を解決するが、真の解決策は、MongoDBののドキュメントを更新することです$inは配列の配列に対しては機能しません。おそらく10genにリクエストを提出する必要があります。

+1

Hehe。今あなたが話している。いくつかのクエリでこの回避策を使用しましたが、$ ninを使用する場合はどうすればよいですか?同じ種類のミステリー行動が現れ、私たちが得たすべてのクエリ結果を疑うようになりました。また、 "array of array"という用語に感謝します。 – dgorur

関連する問題