4

我正在开发一个 Java 系统,其中一部分将表达式从内部表示形式呈现为 MongoDb 查询。我渲染“AND”表达式的方式与渲染“OR”表达式的方式相同。因此,如果我有一个像“category='GIBBLY' AND active=true”这样的表达式,它将呈现为:

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

我知道在这种情况下这不是绝对必要的。我不知道是否存在需要 $and 的情况(在我的系统中,通常会有嵌套的 AND 和 OR,如果这有什么不同的话)。

这对我来说是个问题的原因是 $and 运算符似乎无法用于地理空间查询。像这样的查询:

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

失败并出现“找不到特殊索引:2d”错误。如果我将查询重新执行为:

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

它工作正常。

我试图做一些研究,并在 mongodb-user 组上找到了关于该问题的讨论,其中提到了对地理空间查询中的复合索引的讨论。

我发现的所有信息都没有真正解释为什么 $and 不能与地理空间查询一起使用。我的数据库中根本没有定义复合索引,并且非 $and 查询有效,所以我不确定 $and 在索引方面的工作方式有何不同。

总而言之,我的问题是:

  1. $and 是否有必要,如果有,在什么情况下?

  2. $and 与索引的隐式表示有什么根本区别吗?

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

4

2 回答 2

4

$and 是否有必要,如果有,在什么情况下?

这是经典的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运营商就是为了解决这个问题而设计的。

$and 与索引的隐式表示有什么根本区别吗?

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

为什么 $and 不能用于地理空间查询?

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

另外,请注意 MongoDB 对地理空间索引有特殊限制。您的查询可能没有以理想的方式使用索引。

于 2012-07-19T17:09:31.953 回答
3

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

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

当您需要在单个字段上放置多个过滤器时,$and 运算符是必需的,而这使用逗号语法是不可能的。例如,要查找包含数字 2和数字 10的数组的所有文档,您需要 $and 运算符:

文件:

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

询问:

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

而没有 $and 运算符的查询仅使用“array: 10”并返回两个文档:

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

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

如果它影响您的查询,请随时对与 $and 和地理空间查询相关的 JIRA 票进行投票。

于 2012-07-19T16:41:21.210 回答