2012-07-19 18 views
5

Estoy trabajando en un sistema en Java, parte del cual representa expresiones de una representación interna a una consulta MongoDb. Represento las expresiones "Y" de la misma manera que las expresiones "O". Así que si tengo una expresión como "categoría = 'GIBBLY' y Active = true", que se representa como:

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

entiendo que esto no es estrictamente necesario en este caso. Lo que no puedo entender es si hay siempre un caso donde $ y es necesario (en mi sistema, a menudo habrá AND anidados y OR, si eso hace alguna diferencia).

La razón por la cual este es un problema para mí es que $ y el operador parecen fallar para las consultas geoespaciales. Una consulta como esta:

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

falla con un "no puede encontrar índice especial: 2d" error. Si puedo volver a hacer la consulta como:

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

funciona bien.

Intenté investigar un poco, y encontré una discusión del problema on the mongodb-user group, que se refería a una discusión de compound indexes in geospatial queries.

Ninguna de la información que encontré realmente explica por qué $ y no funciona con la consulta geoespacial. No tengo ningún índice compuesto definido en mi base de datos, y la consulta que no es $ y funciona, por lo que no estoy seguro de cómo $ y funciona de manera diferente con respecto a los índices.

Para resumir, mis preguntas son:

  1. es de $ y nunca es necesario, y si es así, en qué tipo de casos?

  2. ¿Tiene $ y difiere de alguna forma fundamental de la representación implícita con respecto a los índices?

  3. ¿Por qué exactamente $ no funciona con consultas geoespaciales?

+0

¿Es un error si $ nearSphere es la única condición en $ y? – MrKurt

+0

https://jira.mongodb.org/browse/SERVER-4572. No pude encontrar ningún comentario sobre eso también. – pingw33n

+0

Sí - El mismo error si $ nearSphere es la única condición. – dkilmer

Respuesta

4

Es $ y siempre necesario, y si es así, ¿en qué tipo de casos?

Aquí es el clásico SQL

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

Antes de que el operador $and, esto era muy difícil de hacer. No podría hacer lo siguiente:

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

La consulta "parece" correcta, pero no es JSON. Notarás que tengo dos teclas de nivel superior $or. Se supone que esa coma representa el "y", pero no funciona en este caso. El operador $and está diseñado para resolver este problema.

¿Tiene $ y difiere de alguna forma fundamental de la representación implícita con respecto a los índices?

Debe compilar a la misma consulta básica y utilizar los mismos índices. Si no, esto es definitivamente un error.

¿Por qué se hace exactamente $ y no trabajar con consultas geoespaciales?

El comportamiento que está viendo es probablemente un error y debe ser informado: http://jira.mongodb.org/

También, por favor no que MongoDB tiene límites especiales sobre índices geoespaciales. Es posible que su consulta no utilice la indexación de manera ideal.

+0

Gracias, ni siquiera había pensado en las restricciones del mapa JSON. Estaba buscando una forma de ver a qué compilan las consultas MongoDb, pero no pude encontrar nada. Como alguien mencionado anteriormente, hay un boleto [aquí] (https://jira.mongodb.org/browse/SERVER-4572). Por lo tanto, si está leyendo este artículo porque está afectado por el problema, asegúrese de anunciar el boleto. – dkilmer

3

En respuesta a la primera pregunta, como usted señala, el uso de comas en las consultas es un implícito "y":

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

El $ y el operador es necesaria cuando hay que poner varios filtros en un solo campo, que no es posible usando la sintaxis de coma.A modo de ejemplo, para encontrar todos los documentos con una matriz que contiene el número 2 y número 10, se necesita el $ y operador:

documentos:

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

consulta:

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

mientras la consulta sin el operador $ y solo usa "matriz: 10" y devuelve ambos documentos:

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

El uso del operador $ y no debería tener ningún impacto con respecto a los índices. Se usará un único índice para cumplir con la consulta.

No dude en votar por el boleto JIRA relacionado con $ y consultas geoespaciales si esto afecta sus consultas.

+0

Gracias por la descripción extremadamente lúcida. Y mierda: esa situación va a ocurrir constantemente en mi sistema (básicamente, "encontrar todos los proveedores en esta área que proporcionan * todos * los siguientes servicios"). Subí el boleto, espero que lo hagan funcionar. – dkilmer

+0

¿Podría mostrarnos un ejemplo de su consulta y sus datos? Creo que es posible evitar el operador $ add. – Jenna

+0

Lo siento, no vi tu comentario hasta ahora. La consulta de problema es básicamente algo así como la que se encuentra en la publicación original. El verdadero problema es el hecho de que las consultas de MongoDb se representan desde un sistema de expresión. – dkilmer

Cuestiones relacionadas