Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/41.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript MongoDB:如何将数组的$size与另一个文档项进行比较?_Javascript_Node.js_Mongodb_Mongodb Query_Aggregation Framework - Fatal编程技术网

Javascript MongoDB:如何将数组的$size与另一个文档项进行比较?

Javascript MongoDB:如何将数组的$size与另一个文档项进行比较?,javascript,node.js,mongodb,mongodb-query,aggregation-framework,Javascript,Node.js,Mongodb,Mongodb Query,Aggregation Framework,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.68

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"
  },
...
]

您可以使用
$where
查询:

db.turnys.find({ $where: "this.users.length == this.seats" })
您可以将运算符与包含JS表达式的字符串一起使用,也可以直接使用JavaScript函数:

> db.turnys.find(function() { return this.users.length == this.seats })

虽然您可以按照其他人的建议使用
$where
,以便进行跨域比较,但如果可能,我不建议您:

没有索引可用于此搜索。Mongo将扫描每个文档,并针对每个文档执行一个JavaScript表达式以进行跨字段比较。这将是一个昂贵且缓慢的操作

在MongoDB的下一个版本(2.6)中,您将能够在可以比较两个字段的聚合中使用
$size

但是,为了获得最佳性能,我建议您存储一个具体化的布尔值,用于存储
users
数组中的元素数是否等于
seats
中存储的元素数。如果不想获取整个数组以获取计数并与字段“seats”进行比较,可以使用
$inc
(正数和负数)轻松存储当前用户数


如果您必须使用,我建议您尝试进行一些筛选,如果可能的话,这可能有助于避免全表扫描。可能是日期范围,或者检查
用户
数组是否为空,等等。

您可以使用以下任一方法

db.flight.find({"$where":"function() { return this.users.length == this.seats}" })


所有这些都可以满足您的目的,但问题是效率,除非严格必要,否则不应使用“$where”查询:它们比常规查询慢得多,因此请尝试避免使用“$where”查询。

在接受以任何方式使用运算符方面存在实际问题。特别是考虑到你提出的一些“以后”的问题。您需要阅读该操作员的手册页面(如链接中所示)

短点:

  • 操作员调用完全收集扫描,以便进行比较。这在“现实世界”案例中是坏消息,因为没有办法以任何方式“限制”此搜索使用索引,从而减少工作集

  • 本质上,该操作符调用“任意JavaScript执行”。这意味着两件事1)每个文档必须在每次比较时从其本机BSON形式扩展为“JavaScript”对象形式(成本2)您正在为每个和每个比较调用一个“JavaScript”解释器,即而不是本机代码

其中的答案在这方面给了您有效的警告,尽管它没有给您提供实际的答案。这就是:

如前所述,如果这对您很重要,您应该在文档中保留“数组”元素的“计数”。但是,虽然您可能认为这是有效的,但适当的比较如下所示

因此,我们假设您确实按照建议使用了
$inc
,在文档中保留了
total_users
字段

db.collection.aggregate([
{“$project”:{
“gId”:1,
“alloc”:{“$eq”:[“$total_users”,“$seats”]}
}},
{“$match”:{“alloc”:1}
])
基本上,您可以在文档中选择所需的所有字段,只要您通过简单地执行“逻辑”比较(如运算符所示)来进行“alloc”字段所示的比较即可

在未来的版本中(在编写本文时很快),您甚至可以在“聚合”操作中找到数组的名称。因此,“而不是”在“数组”成员上保留计数器,您可以这样做:

db.collection.aggregate([
{“$project”:{
“gId”:1,
“alloc”:{“$eq”:[{“$size”:“$users”},“$seats”]}
}},
{“$match”:{“alloc”:1}
])
但这自然会带来“成本”,因此最好的选择还是根据您的需要在文档上保留“计数器”

虽然这里的两种方法都*仍然**导致“收集扫描”(在此上下文中,因为存在其他$match条件),但最终结果将比其他答案中显示的“JavaScript”执行速度快很多倍


使用“本机代码”方法作为最佳实践解决方案。

我想对这个伟大的答案也给出+1,但我还没有足够的声誉去投票。到时候我会投赞成票的。谢谢你能告诉我同样的事情吗?我怎么能为不平等做。对于我的数据库,我尝试了两种方法,但都不起作用。我有两个数组而不是一个数组。1.db.us_election_nodes_with_tweet.find({$and:[{result:{{ne:{size:{tweets},{$size:$tweetIds}]},{result:{$exists:true}}]})。pretty()和aslo 2。db.us_election_nodes_with_tweets.aggregate([{“$project”:{“\u id”:1,“alloc”:{“$ne”:[{“$size”:“$tweets”},{“$size”:“$tweets”},{“$size”:“$tweetIds”}},{“$match”:{“alloc”:1}])我想给它一个+1,但还没有名声。等我回来再做。谢谢
db.turnys.find({ $where: "this.users.length == this.seats" })
db.turnys.find(function() { return this.users.length == this.seats })