我想知道如何在mongodb查询中启用数组大小的不等式。
例如,我有以下两个查询:
> db.userStats.count({sessions:{$size:1}})
1381
> db.userStats.count({sessions:{$size:{$gt:0}}})
0
如果$gt
按预期工作,则第二个查询的结果会有所不同,导致数字至少为1381.
第二个查询有什么问题,如何修复它以达到我想要的结果?
感谢
答案 0 :(得分:4)
您不能像$size
的文档中实际引用的那样执行此操作。因此,运算符单独评估“文字”结果,不能与“范围运算符”一起使用,例如您要求的。
您唯一真正的选择是通过使用$not
运算符否定条件来要求“大小”“不等于0”。这完全有效:
db.userStats.count({ "sessions": { "$not": { "$size": 0 } } });
或者在聚合框架中使用$size
的其他版本进行测试,只要您的MongoDB版本是2.6或更高版本:
db.userStats.aggregate([
{ "$group": {
"_id": null,
"count": {
"$sum": {
"$cond": [
{ "$gt": [ { "$size": "$sessions", 0 } ] },
1,
0
]
}
}
}}
])
可能还有$where
形式的JavaScript评估:
db.userStats.count(function() { return this.sessions.length > 0 });
但可能比上一版本慢。
或者您实际上可以使用"dot notation"和$exists
运算符执行此操作:
db.userStats.count({ "sesssions.0": { "$exists": true } });
一般的想法是,如果索引0
处有一个元素,那么该数组有一定的长度。
这一切都取决于你的方法,但这些形式中的任何一种都能得到正确的结果。
但是对于MongoDB的“最佳”性能,请不要使用任何这些方法。而是将数组“length”保留为您正在检查的文档的属性。这可以“索引”,并且发出的查询实际上可以访问该索引,而上述任何一个都无法做到。
保持这样:
db.userStats.update(
{ "_id": docId, "sessions": { "$ne": newItem } },
{
"$push": { "sessions": newItem },
"$inc": { "countSessions": 1 }
}
)
或删除:
db.userStats.update(
{ "_id": docId, "sessions": newItem },
{
"$pull": { "sessions": newItem },
"$inc": { "countSessions": -1 }
}
)
然后你可以查询“countSesssions”,它也可以索引最佳性能:
db.userStats.find({ "countSessions": { "$gt": 0 } })
这是“最好”的方式。
答案 1 :(得分:2)
$ size不接受一系列值。见http://docs.mongodb.org/manual/reference/operator/query/size/
要为一系列值选择$ size,例如从1到3,您可以使用$或
db.userStats.count( { $or: [ {sessions:{$size:1}}, {sessions:{$size:2}}, {sessions:{$size:3}} ] } )
当然,$或者是一种有效但不是很好的解决方案。按照MongoDB的建议:
根据具有不同数量的字段选择文档 元素,创建一个在添加时递增的计数器字段 元素到一个领域。