4

私はJavaのシステムに取り組んでおり、その一部は内部表現からMongoDbクエリに式をレンダリングします。「OR」式をレンダリングするのと同じ方法で「AND」式をレンダリングします。したがって、「category ='GIBBLY' AND active = true」のような式がある場合、次のようにレンダリングされます。

{$and:[{"category":"GIBBLY"},{"active":true}]}

この場合、これは必ずしも必要ではないことを理解しています。私が理解できないのは、$ andが必要な場合があるかどうかです私のシステムでは、それが何か違いを生む場合、ネストされたANDとORがしばしばあります)。

これが私にとって問題である理由は、$and演算子が地理空間クエリで失敗するように見えるためです。このようなクエリ:

{"$and":[{"loc":{"$nearSphere":[-79.75 , 43.5], "$maxDistance":0.00156787}}, {"active":true}]}

「特別なインデックスが見つかりません:2d」エラーで失敗します。次のようにクエリをやり直すと、次のようになります。

{"loc":{"$nearSphere":[-79.75 , 43.5], "$maxDistance":0.00156787}, "active":true}

それはうまくいきます。

いくつかの調査を試みたところ、mongodb-userグループでこの問題の議論が見つかりました。これは、地理空間クエリの複合インデックスの議論に言及しています。

私が見つけた情報のどれも、なぜ正確に$andが地理空間クエリで機能しないのかを実際に説明していません。データベースに複合インデックスがまったく定義されておらず、$ and以外のクエリが機能するため、$andがインデックスに関してどのように異なるかがわかりません。

要約すると、私の質問は次のとおりです。

  1. $ andは必要ですか?もしそうなら、どのような場合に?

  2. $ andは、インデックスに関して暗黙の表現と基本的に異なりますか?

  3. $ andが地理空間クエリで機能しないのはなぜですか?

4

2 に答える 2

4

$ andは必要ですか?もしそうなら、どのような場合に?

これが古典的なSQLです

SELECT * FROM Table
WHERE (x = 1 OR y = 0)
AND   (w = 1 OR z = 0)

オペレーターの前は$and、これを行うのは非常に困難でした。次のことはできませんでした。

db.Table.find({$or: [{x:1},{y:0}] , $or: [{w:1},{z:0}]})

クエリは「正しく」見えますが、無効なJSONです。私が2つのトップレベルの$orキーを持っていることに気付くでしょう。そのコンマは「and」を表すことになっていますが、この場合は機能しません。

$andオペレーターは、この問題を解決するように設計されています。

$ andは、インデックスに関して暗黙の表現と基本的に異なりますか?

同じ基本クエリにコンパイルし、同じインデックスを使用する必要があります。そうでない場合、これは間違いなくバグです。

$ andが地理空間クエリで機能しないのはなぜですか?

表示されている動作はおそらくバグであり、報告する必要があります:http: //jira.mongodb.org/

また、MongoDBには地理空間インデックスに特別な制限があることに注意してください。クエリが理想的な方法でインデックスを使用していない可能性があります。

于 2012-07-19T17:09:31.953 に答える
3

最初の質問への回答として、ご指摘のとおり、クエリでコンマを使用することは暗黙の「and」です。

db.collection.find({name: "Jenna", number: 1})

$ and演算子は、1つのフィールドに複数のフィルターを配置する必要がある場合に必要です。これは、コンマ構文では不可能です。例として、番号2と番号10を含む配列を持つすべてのドキュメントを検索するには、$and演算子が必要です。

ドキュメント:

{_id: 1, array: [1, 10]}
{_id: 2, array: [2, 10]}

クエリ:

> db.collection.find({$and: [{array: 2}, {array: 10}]})
{_id: 2, array: [2, 10]}

一方、$ and演算子を使用しないクエリは、「array:10」のみを使用し、両方のドキュメントを返します。

> db.collection.find({array: 2, array: 10})
{_id: 1, array: [1, 10]}
{_id: 2, array: [2, 10]}

$ and演算子を使用しても、インデックスに関しては影響がありません。クエリを満たすために単一のインデックスが使用されます。

クエリに影響する場合は、$andおよび地理空間クエリに関連するJIRAチケットに自由に投票してください。

于 2012-07-19T16:41:21.210 に答える