web-dev-qa-db-ja.com

MongoDBネストされた配列クエリ

another 質問へのコメントとしてこれを尋ね、mongodb-userに question を投稿しました。今のところ回答がないので、別の質問をすることに頼っています。

ドキュメント 状態:

フィールドが配列を保持している場合、$ in演算子は、指定された配列の値に一致する少なくとも1つの要素を含む配列をフィールドが保持しているドキュメントを選択します(例:など)

私は使用しています:

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を放棄することを検討しています。

ありがとう!

40
dgorur

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

詳細 MongoDBの配列の配列のクエリ

8
dgorur

いくつかのクエリを実行した後、$ inは配列の配列では機能しませんという結論に達しました。

代わりに$elemMatchを使用することもできますが、機能しますが、MongoDBのドキュメントでは警告されていません。

このドキュメントを作成しました:

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

フィールド「items」は文字列の配列であり、このクエリは完全に機能することに注意してください。

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にリクエストを送信する必要があります。

39
AntonioOtero

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

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

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

$ allが機能しているのは、複数の値を持つこのフィールドを持つドキュメントを教えてください。この配列のすべての値(クエリ内)がそのフィールドに含まれているからです。 (編集済み)

入手するのは難しいかもしれませんが、それぞれについてドキュメントに書かれていることを見てください:

$ allは、フィールドは配列を保持し、すべての要素を含む(e.g. <value>, <value1>, etc.)配列内。

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

それが役に立てば幸い

5
AntonioOtero