私はこのように構造化されたコレクションを持っています:
{
_id: 1,
score: [
{
foo: 'a',
bar: 0,
user: {user1: 0, user2: 7}
}
]
}
少なくとも1つの「スコア」(スコア配列の要素)があり、特定の値が「バー」で空でない「ユーザー」サブドキュメントがあるすべてのドキュメントを検索する必要があります。
これは私が思いついたものです(そしてそれはうまくいくように見えました):
db.col.find({score: {"$elemMatch": {bar:0, user: {"$not":{}} }}})
しかし、私はこのエラーを受け取ります:
error: { "$err" : "$not cannot be empty", "code" : 13030 }
これを行う他の方法は?
理解した: { 'score.user': { "$gt": {} } }
は空でないドキュメントに一致します。
私はあなたのスキーマを完全に理解しているとは思いませんが、おそらく最も簡単な方法はscore.userに「空の」値を設定しないことでしょう。
代わりに、意図的にnotコンテンツがない場合、ドキュメントにそのフィールドがありますか?
次に、クエリは次のようになります...
> db.test.find({ "score" : { "$elemMatch" : { bar : 0, "user" : {"$exists": true }}}})
つまり、score.barでミアの存在($ exists、 score.userのdocs )を参照してください(値がある場合は存在しますか?)
editied:おっと、あなたが持っていた$ elemMatchを逃しました...
おそらく、user
ドキュメント内のユーザーを追跡する補助配列を追加する必要があります。
{
_id: 1,
score: [
{
foo: 'a',
bar: 0,
users: ["user1", "user2"],
user: {user1: 0, user2: 7}
}
]
}
次に、新しいユーザーをアトミックに追加できます。
> db.test.update({_id: 1, score: { $elemMatch: {bar: 0}}},
... {$set: {'score.$.user.user3': 10}, $addToSet: {'score.$.users': "user3"}})
ユーザーを削除します。
> db.test.update({_id: 1, score: { $elemMatch: {bar: 0}}},
... {$unset: {'score.$.user.user3': 1}, $pop: {'score.$.users': "user3"}})
クエリのスコア:
> db.test.find({_id: 1, score: {$elemMatch: {bar: 0, users: {$not: {$size: 0}}}}})
存在しないユーザーのみを追加し、user
ドキュメントから既存のユーザーを削除することがわかっている場合は、users
を配列ではなくカウンターに簡略化できますが、上記の方が復元力があります。
$ size演算子を見て、配列のサイズを確認してください。