2012-07-19 56 views
5

我正在研究Java中的系统,其中的一部分将表达式从内部表示呈现到MongoDb查询。我呈现“AND”表达式的方式与呈现“OR”表达式的方式相同。

{$and:[{"category":"GIBBLY"},{"active":true}]}

我明白,这不是绝对必要在这种情况下:如果我有一个像“一类=‘GIBBLY’和积极=真实”的表达,将它作为渲染。我无法弄清楚是否有这种情况下,$和是必要的(在我的系统中,如果有区别的话,通常会有嵌套的AND和OR)。

这对我来说是个问题,原因是$和operator对于地理空间查询似乎失败了。像这样的查询:

{"$and":[{"loc":{"$nearSphere":[-79.75 , 43.5], "$maxDistance":0.00156787}}, {"active":true}]}

失败,出现“无法找到特殊的索引:2D”的错误。如果我重新做查询为:

{"loc":{"$nearSphere":[-79.75 , 43.5], "$maxDistance":0.00156787}, "active":true}

它工作正常。

我试图做一些研究,并发现讨论的问题on the mongodb-user group,其中讨论了compound indexes in geospatial queries

我发现的任何信息都不能解释为什么正好是$,并且不适用于地理空间查询。我的数据库中没有定义任何复合索引,非$和查询都可以工作,所以我不确定$和$在索引方面的工作方式不同。

总之,我的问题是:

  1. 为$和以往任何时候都需要的,如果是这样,在什么样的情况下?

  2. 是否$并且在某些基本方面与隐式表示方式在索引方面有所不同?

  3. 为什么$和不适用于地理空间查询?

+0

如果$ nearSphere是$和?中唯一的条件,它会发生错误吗? – MrKurt 2012-07-19 16:03:32

+0

https://jira.mongodb.org/browse/SERVER-4572。我也找不到任何评论。 – pingw33n 2012-07-19 16:05:57

+0

是 - 如果$ nearSphere是唯一的条件,则会出现相同的错误。 – dkilmer 2012-07-19 16:23:02

回答

4

$是否必要,如果是的话,在什么情况下?

这里是典型的SQL

SELECT * FROM Table 
WHERE (x = 1 OR y = 0) 
AND (w = 1 OR z = 0) 

此前$and运营商,这是很难做到的。您无法执行以下操作:

db.Table.find({$or: [{x:1},{y:0}] , $or: [{w:1},{z:0}]}) 

查询“看起来”正确,但它是无效的JSON。你会注意到我如何拥有两个顶级密钥$or。这个逗号应该代表“和”,但在这种情况下它不起作用。

$and运算符旨在解决此问题。

是否$与隐式表示在索引方面有某些根本差异?

它应该编译为相同的基本查询并使用相同的索引。如果没有,这绝对是一个错误。

为什么确切$并且不适用于地理空间查询?

您所看到的行为是一个可能的错误,并应报告:http://jira.mongodb.org/

另外,请不就是MongoDB中对地理空间信息的索引特殊限制。您的查询可能不会以理想的方式使用索引。

+0

谢谢 - 甚至没有想过JSON地图的限制。我正在寻找一种方法来查看MongoDb查询编译到的内容,但找不到任何内容。正如上面提到的人,有一张票[这里](https://jira.mongodb.org/browse/SERVER-4572)。因此,如果您正在阅读此项目,因为您受到该问题的影响,请确保升级票证。 – dkilmer 2012-07-20 16:14:08

3

在回答你的第一个问题,正如你指出,在查询中使用逗号是隐式“和”:

db.collection.find({name: "Jenna", number: 1}) 

的$,当你需要把多个过滤器操作是必要的在单个字段上,这是使用逗号语法无法实现的。作为一个例子,找到与含2号 10号阵列中的所有文件,你需要$和运营商:

文件:

{_id: 1, array: [1, 10]} 
{_id: 2, array: [2, 10]} 

查询:

> db.collection.find({$and: [{array: 2}, {array: 10}]}) 
{_id: 2, array: [2, 10]} 

而没有$和操作符的查询仅使用“array:10”并返回两个文档:

> db.collection.find({array: 2, array: 10}) 
{_id: 1, array: [1, 10]} 
{_id: 2, array: [2, 10]} 

使用$和运算符应该对索引没有影响。将使用单个索引来满足查询。

如果它影响您的查询,请随意投票与$和和地理空间查询相关的JIRA票据。

+0

感谢您的非常清晰的描述。废话 - 这种情况会不断在我的系统中发生(基本上,“找到这个地区提供以下所有服务的所有提供商”)。我提出了票 - 希望他们会做这项工作。 – dkilmer 2012-07-19 16:55:52

+0

你能向我们展示一个你的查询和你的数据的例子吗?我认为可以避免$ add操作符。 – Jenna 2012-07-24 01:20:55

+0

对不起 - 直到现在才看到您的评论。问题查询基本上与原始文章中的问题类似。真正的问题是MongoDb查询是从表达式系统渲染出来的。 – dkilmer 2012-08-03 14:51:21