【问题标题】:Meteorjs collection find with $where使用 $where 查找 Meteorjs 集合
【发布时间】:2016-01-29 13:13:43
【问题描述】:

我有一个带有ticker 字段的集合的meteorjs 应用程序。
我需要$where 语句,因为我想比较同一集合中的两个字段:

Tickers.find({$where: function() { return (this.price < this.value); }})

它不起作用,我用$where 做了一个更简单的测试。
在服务器端,当我运行这个查询时:

var t = Tickers.find({ticker:'AAPL'});

t 包含正确的值:具有“AAPL”代码值的一项。当我使用时:

t = Tickers.find({$where: function() { return (this.ticker === 'AAPL'); }});

t 包含集合中的所有项目。
相同的$where 查询在客户端工作,但我不想发布(巨大的)集合在客户端进行查询。

【问题讨论】:

  • 您能否更具体地说明它是如何不起作用的?您收到的是错误还是错误的值?

标签: javascript mongodb meteor


【解决方案1】:

您需要将 $where 函数作为字符串传递,而不是作为实际函数传递。这是 Mongo 处理和运行函数所必需的(在 Node.js 中没有完成)。关注forum thread 了解更多信息。

因此将您的查询更改为

Tickers.find({"$where": "function() { return (this.price < this.value); }"})

或者直接传入字符串比较

Tickers.find("this.price < this.value");

但是,请记住,这不会很好,因为使用 $where 运算符会调用 JavaScript 引擎来评估每个文档上的 Javascript 代码并检查每个文档的条件。如果可以的话,建议结合索引查询,这样查询可能会更快。

一些considerations在使用$where时必须注意的:

不要使用全局变量。

$where 评估 JavaScript,不能利用索引。 因此,当您表达查询时,查询性能会提高 使用标准的 MongoDB 运算符(例如,$gt$in)。一般来说,你 仅当您无法使用其他方式表达您的查询时,才应使用 $where 操作员。如果您必须使用 $where,请尝试至少包含另一个 标准查询运算符来过滤结果集。单独使用 $where 需要表扫描。使用普通的非$where 查询语句 提供以下性能优势:

MongoDB 将在 $where 之前评估查询的非$where 组件 陈述。如果非$where 语句不匹配任何文档,MongoDB 不会使用 $where 执行任何查询评估。非$where 查询语句可以使用索引。

避免使用 $where 运算符的另一个建议是创建一个额外的计算非规范化字段,例如 price_difference,这是价格和价值之间的差异(价值 - 价格),然后您可以查询为:

Tickers.find({ "price_difference": { "$gt": 0 }});

但是,如果集合非常大,这样的低选择性字段仍然不会产生良好的索引性能,因此使用这种方法进行索引的候选集很大。

【讨论】:

  • 感谢 cridam 的好主意:我将创建额外的计算非规范化字段。
猜你喜欢
  • 2018-01-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-24
  • 2016-03-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多