我有一个如此结构的集合:
{
_id: 1,
score: [
{
foo: 'a',
bar: 0,
user: {user1: 0, user2: 7}
}
]
}
我需要找到所有至少有一个'得分'(得分数组中的元素)且具有特定值'bar'和非空'用户'子文档的文档。
这就是我提出的(似乎应该有效):
db.col.find({score: {"$elemMatch": {bar:0, user: {"$not":{}} }}})
但是,我收到了这个错误:
error: { "$err" : "$not cannot be empty", "code" : 13030 }
还有其他方法吗?
答案 0 :(得分:64)
想出来:{ 'score.user': { "$gt": {} } }
将匹配非空文档。
答案 1 :(得分:3)
我不确定我是否完全了解您的架构,但最直接的方法可能是 score.user 没有“空”值?
如果没有内容,则有意不在文档中包含该字段?
那么您的查询可能就像......
> db.test.find({ "score" : { "$elemMatch" : { bar : 0, "user" : {"$exists": true }}}})
即。在 score.bar 中查找您想要的值(在这种情况下为0),检查的mear存在($ exists,see docs) score.user (如果它有值,那么它会存在吗?)
编辑:oops我错过了你的$ elemMatch ......
答案 2 :(得分:1)
您可能想要添加一个辅助数组来跟踪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
简化为计数器而不是数组,但以上内容更多弹性的。
答案 3 :(得分:0)
查看$ size运算符以检查数组大小。