5

特定のフィールドが欠落しているか、Python で false と評価される値を持つドキュメントの Mongo コレクションをクエリしたいと考えています。これには、アトミック値null, 0, ''(空の文字列) ,falseが含まれます[]。ただし、そのような値 (['foo', '']またはなど[''])を含む配列は偽ではなく、一致してはなりませ。Mongo の構造化クエリで (JavaScript に頼らずに) これを行うことはできますか?

$type役に立たないようです:

> db.foo.insert({bar: ['baz', '', 'qux']});
> db.foo.find({$and: [{bar: ''}, {bar: {$type: 2}}]});
{ "_id" : ObjectId("50599937da5254d6fd731816"), "bar" : [ "baz", "", "qux" ] }
4

2 に答える 2

4

これはうまくいくはずです

db.test.find({$or:[{a:{$size:0}},{"a.0":{$exists:true}}]})

aフィールドに0キーを含むオブジェクトが含まれていないことを確認してください。

例えば

> db.test.find()

{ "_id": ObjectId("5059ac3ab1cee080a7168fff"), "bar": [ "baz", "", "qux" ] }
{ "_id": ObjectId("5059ac48b1cee080a7169000"), "hello": 1, "bar": false, "world": 34 }
{ "_id": ObjectId("5059ac53b1cee080a7169001"), "hello": 1, "world": 42 }
{ "_id": ObjectId("5059ac60b1cee080a7169002"), "hello": 13, "bar": null, "world": 34 }
{ "_id": ObjectId("5059ac6bb1cee080a7169003"), "hello": 133, "bar": [ ], "world": 334 }
{ "_id": ObjectId("5059b36cb1cee080a7169004"), "hello": 133, "bar": [ "" ], "world": 334 }
{ "_id": ObjectId("5059b3e3b1cee080a7169005"), "hello": 133, "bar": "foo", "world": 334 }
{ "_id": ObjectId("5059b3f8b1cee080a7169006"), "hello": 1333, "bar": "", "world": 334 }
{ "_id": ObjectId("5059b424b1cee080a7169007"), "hello": 1333, "bar": { "0": "foo" }, "world": 334 }

> db.test.find({$or: [{bar: {$size: 0}}, {"bar.0": {$exists: true}}]})

{ "_id": ObjectId("5059ac3ab1cee080a7168fff"), "bar": [ "baz", "", "qux" ] }
{ "_id": ObjectId("5059ac6bb1cee080a7169003"), "hello": 133, "bar": [ ], "world": 334 }
{ "_id": ObjectId("5059b36cb1cee080a7169004"), "hello": 133, "bar": [ "" ], "world": 334 }
{ "_id": ObjectId("5059b424b1cee080a7169007"), "hello": 1333, "bar": { "0": "foo" }, "world": 334 }
于 2012-09-19T12:04:34.987 に答える
1

私はこれを見つけました: https://jira.mongodb.org/browse/SERVER-1854?page=com.atlassian.jira.plugin.system.issuetabpanels:changehistory-tabpanel昔から。

MongoDB 2.0.1 でそれを複製できます (別のものとして認識されるかどうかを確認するために少し遊んでみました):

> db.g.find()
{ "_id" : ObjectId("50599eb65395c82c7a47d124"), "bar" : [ "baz", "", "qux" ] }
{ "_id" : ObjectId("5059a0005395c82c7a47d125"), "a" : 3, "b" : { "a" : 1, "b" : 2 } }
> db.g.find({bar: {$type: 4}});
> db.g.find({a: {$type: 2}});
> db.g.find({a: {$type: 16}});
> db.g.find({bar: {$type: 16}});
> db.g.find({bar: {$type: 2}});
{ "_id" : ObjectId("50599eb65395c82c7a47d124"), "bar" : [ "baz", "", "qux" ] }
> db.g.find({bar: {$type: 3}});
> db.g.find({b: {$type: 3}});
{ "_id" : ObjectId("5059a0005395c82c7a47d125"), "a" : 3, "b" : { "a" : 1, "b" : 2 } }

そして、4 を使用すると、配列を含むドキュメント$typeを取得できません。ピックアップされます。$type 3

バグが発生している可能性があります。MongoDB サイト (jira.mongodb.org) で JIRA を提出すると、問題の解決に役立つ場合があります。

ただし、$typeop では問題が解決しない場合があります。これは、存在を照会する方法で要素がない場合、フィールドを完全に設定解除するなどのクライアント側の方法を介して行う方がよい場合があります。これにより、クエリ パターンが標準化され、一般的な統合が容易になります。

したがって、ここでの私の個人的な推奨事項は、「誤った」値を 1 つの一致した値に標準化することです。

編集

元のバグが重複としてマークされていることに気付きました (そのためクローズされています) が、どのように重複しているのかはわかりません。これらの配列は、オブジェクトとしてではなく文字列として取得されます。これは、おそらく $type がフィールド自体 (またはそのようなもの) ではなく、そのフィールド内のすべての要素に作用するためです。

私はまだ JIRA を開いて、配列をまったく取得できないことを強調します。

于 2012-09-19T10:50:06.160 に答える