He estado tratando de combinar los métodos y() y o() de la interfaz de Consulta para crear un conjunto de condiciones donde hay 2 listas de criterios, y al menos uno de cada debe estar satisfechoCompleja AND-OR consulta en Morphia
He leído this discussion y he estado tratando de usar el Query.and() para combinar mis dos $ o cláusulas.
En esencia, yo estoy tratando de decir:
Criteria[] arrayA;
Criteria[] arrayB;
// Programatically populate both arrays
Query q = dao.createQuery().and(
q.or(arrayA),
q.or(arrayB)
);
estoy usando matrices de criterios porque tengo que recorrer varias entradas diferentes para generar los criterios particulares que necesito, y este enfoque funciona cuando Estoy usando solo $ o, pero no puedo hacer que Morphia genere la consulta que espero cuando intento incluir $ o cláusulas en $ y como expliqué anteriormente. Me parece que no hay $ y la consulta y el segundo $ o ha sobrescrito el primero, como si simplemente hubiera llamado o() dos veces.
EG I espera una consulta que se genera de esta manera:
{
"$and": {
"0": {
"$or": {
"0": //Some criteria,
"1": //Some criteria,
"2": //Some criteria,
}
},
"1": {
"$or": {
"0": //Some other criteria,
"1": //Some other criteria,
"2": //Some other criteria,
}
}
}
Sin embargo, acabo de recibir una consulta como esta:
{
"$or": {
"0": //Some other criteria,
"1": //Some other criteria,
"2": //Some other criteria,
}
}
no puedo ver mucha documentación, pero mirando el caso de prueba, esta parece ser la forma correcta de hacerlo. ¿Alguien puede ayudar a arrojar alguna luz sobre por qué esto no está funcionando como espero?
(Esta pregunta fue cross-posted to the Morphia mailing list, ya que no estoy seguro de qué lugar sería obtener la mejor respuesta)
Editar 0:
actualización: Repaso a esto, he comprobado el código de prueba Morphia y todo funciona bien, no he podido reproducir mi problema en el código de prueba.
Por lo tanto, creé un nuevo proyecto para tratar de obtener un ejemplo de trabajo de la consulta que deseo. Sin embargo, me encontré con el mismo problema, incluso con un proyecto de prueba barebones.
El proyecto se mavenised y el POM es:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>test</groupId>
<artifactId>test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Test</name>
<dependencies>
<dependency>
<groupId>com.google.code.morphia</groupId>
<artifactId>morphia</artifactId>
<version>0.99</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<!-- Force the use of the latest java mongoDB driver -->
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
<version>2.7.3</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>
tengo una clase TestEntity:
import java.util.Map;
import com.google.code.morphia.annotations.Entity;
@Entity
public class TestEntity {
Map<String, Integer> map;
}
Y por último, mi clase de prueba:
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.Map;
import com.google.code.morphia.Datastore;
import com.google.code.morphia.Morphia;
import com.google.code.morphia.query.Query;
import com.google.code.morphia.query.QueryImpl;
import com.mongodb.Mongo;
import com.mongodb.MongoException;
public class Test {
static Mongo mongo;
static Morphia m;
static Datastore ds;
static {
mongo = null;
try {
mongo = new Mongo();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (MongoException e) {
e.printStackTrace();
}
m = new Morphia();
ds = m.createDatastore(mongo, "test");
}
public static void main(String[] args) {
populate();
query();
}
public static void query() {
Query<TestEntity> q = ds.createQuery(TestEntity.class);
q.and(q.or(q.criteria("map.field1").exists()),
q.or(q.criteria("map.field2").exists()));
Iterable<TestEntity> i = q.fetch();
for (TestEntity e : i) {
System.out.println("Result= " + e.map);
}
QueryImpl<TestEntity> qi = (QueryImpl<TestEntity>) q;
System.out
.println("Query= " + qi.prepareCursor().getQuery().toString());
}
public static void populate() {
TestEntity e = new TestEntity();
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("field1", 1);
map.put("field2", 2);
e.map = map;
ds.save(e);
}
}
Para mí, el código anterior no produce los $ correctos y la consulta, pero no puedo ver por qué
- habría sido bueno dar el último ejemplo de trabajo. –
Hola @RussBateman, el código no cambió, parece que hay un problema en la versión 0.99 que se resuelve en 0.99.1-SNAPSHOT, así que simplemente cambiamos la versión de la biblioteca que estamos usando (no es ideal, pero el mejor opción que tuvimos) – chrisbunney
Incluso con 0.99.1-SNAPSHOT todavía tengo el problema con Query.and(). Está bien siempre que los Criterios sean campos simples, pero cuando tiene $ o un criterio incluido en $ y, fallará –