MongoDB:如何在mongo控制台和JavaScript中使用Node.js这样做:
db.turnys.find( { users:{$size:seats } } )
turnydb.turnys看起来像这样:
[
{
"gId": "5335e4a7b8cf51bcd054b423",
"seats": 2,
"start": "2014-03-30T14:23:29.688Z",
"end": "2014-03-30T14:25:29.688Z",
"rMin": 800,
"rMax": 900,
"users": [],
"_id": "533828e1d1a483b7fd8a707a"
},
{
"gId": "5335e4a7b8cf51bcd054b423",
"seats": 2,
"start": "2014-03-30T14:23:29.688Z",
"end": "2014-03-30T14:25:29.688Z",
"rMin": 900,
"rMax": 1000,
"users": [],
"_id": "533828e1d1a483b7fd8a707b"
},
...
]
答案 0 :(得分:2)
虽然您可以按照其他人的建议使用$where
进行跨领域比较,但如果可能的话,我不建议使用它:
此搜索无法使用任何索引。 Mongo将扫描每个文档并对每个文档执行JavaScript表达式以进行跨字段比较。这将是一个昂贵且缓慢的操作。
进入下一版本的MongoDB(2.6),您将能够在聚合中使用$size
operator,这可以比较两个字段。
但是,为了获得最佳性能,我建议您存储一个物化布尔值,用于存储users
数组中元素的数量是否等于seats
中存储的数量。如果您不想获取整个数组以获取计数并与字段“席位”进行比较,则可以使用$inc
(正数和负数)轻松存储当前用户的数量。
如果您必须使用$where
,我建议您尝试进行一些过滤,以避免全表扫描。可能是日期范围,或者检查users
数组是否为空,等等。
答案 1 :(得分:1)
您可以使用$where
查询:
db.turnys.find({ $where: "this.users.length == this.seats" })
答案 2 :(得分:1)
您可以将$where运算符与包含JS表达式的String或直接使用JavaScript函数一起使用:
> db.turnys.find(function() { return this.users.length == this.seats })
答案 3 :(得分:1)
您可以使用以下任何一种方法
db.flight.find({"$where":"function() { return this.users.length == this.seats}" })
或
db.turnys.find({ $where: "this.users.length == this.seats" })
或
db.turnys.find(function() { return this.users.length == this.seats })
这些都将满足您的目的,但事情是效率,除非必要,否则不应使用“$ where”查询:它们比常规查询慢得多,因此请尝试避免使用“$ where”进行查询。
答案 4 :(得分:1)
接受以任何方式使用$where
运算符时存在真正的问题。特别是考虑到你提出的一些“后期”问题。您需要 阅读此运营商的手册页(如链接中所示)。
短点:
$where
运算符调用完整集合扫描以进行比较。这是“真实世界”案例中的错误新闻,因为无法“约束”此搜索以任何方式使用索引,从而减少工作集。
本质上,此运算符调用“任意JavaScript执行”。这意味着两件事。 1 。)每个文档必须从其本机BSON表单扩展为“JavaScript”对象表单(成本),以进行每次比较。 2 。)您正在调用“JavaScript”解释器,即不本机代码,每个每次比较。
< / LI>One的答案为您提供了有效警告,但它没有为您提供实际答案。所以这就是:
如上所述,是 应该实际上保留文档中“数组”元素的“计数”,如果这对您很重要的话。但是,虽然您可能已将此视为有效,但正确比较完成如下。
因此,我们假设您确实按照建议使用$inc
,以便在文档中保留total_users
字段。
db.collection.aggregate([
{ "$project": {
"gId": 1,
"alloc": { "$eq": [ "$total_users", "$seats" ] }
}},
{ "$match": { "alloc": 1 } }
])
其中基本上你可以$project
文档中你想要的所有字段,只要你通过“alloc”字段进行比较,只需做一个“逻辑” “与$eq
运算符一起显示的比较。
在将来的版本中(编写后不久),您甚至可以在“聚合”操作中找到数组的$size
。所以“而不是”在“数组”成员上保留一个计数器,你可以这样做:
db.collection.aggregate([
{ "$project": {
"gId": 1,
"alloc": { "$eq": [ { "$size": "$users" }, "$seats" ] }
}},
{ "$match": { "alloc": 1 } }
])
但自然会带来“成本”,所以仍然最好的选择是根据您的需要在文档上保留“反击”。
虽然两个接近这里*仍然**导致“集合扫描”(在此上下文中,因为没有其他$匹配条件),最终结果比其他答案中显示的“JavaScript”执行速度快倍。
使用“本机代码”方法作为最佳实践解决方案。