Komplexen UND-ODER-Abfrage in Morphia
Ich habe versucht zu kombinieren, und() und oder () - Methode der Abfrage-Schnittstelle zu erstellen, die eine Reihe von Bedingungen, wo es 2 Listen von Kriterien und mindestens eines von jedem erfüllt werden müssen.
Lese ich diese Diskussion und haben versucht, verwenden Sie die Abfrage.und() zu kombinieren meine beiden $oder Klauseln.
Im Grunde genommen bin ich versucht zu sagen:
Criteria[] arrayA;
Criteria[] arrayB;
//Programatically populate both arrays
Query q = dao.createQuery().and(
q.or(arrayA),
q.or(arrayB)
);
Bin ich mit arrays von Kriterien, denn ich habe eine Schleife durch die verschiedenen Eingänge zu erzeugen, die bestimmten Kriterien, die ich brauche, und dieser Ansatz funktioniert, wenn ich bin nur mit einem einzigen $oder, aber ich kann Sie nicht Morphia, die zum generieren der Abfrage, die ich erwarten, wenn ich versuchen Sie, und beide $oder Klauseln in den $ - und wie ich oben erklärt. Ich finde, dass es keine $und Abfrage und das zweite $hat oder überschrieben, die erste, gerade so, als hätte ich einfach angerufen oder() zweimal.
E. g erwarte ich eine Abfrage generiert werden, wie diese:
{
"$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,
}
}
}
Jedoch bekomme ich nur eine Abfrage wie diese:
{
"$or": {
"0": //Some other criteria,
"1": //Some other criteria,
"2": //Some other criteria,
}
}
Ich kann nicht viel Dokumentation, aber ein Blick in den test-Fall, dies scheint der richtige Weg zu gehen über diese. Kann mir jemand helfen, alle vergossen Licht auf, warum dies nicht so funktioniert wie ich erwarte?
(Diese Frage wurde cross-posted auf der Morphia-mailing-Liste, da bin ich mir nicht sicher, welchen Platz bekommen würde die beste Antwort)
Bearbeiten 0:
Update: Erneuten Besuch dieser, ich habe aus der Morphia-test-code, und jedes Ding läuft gut, ich habe nicht in der Lage zu reproduzieren mein Problem in den test-code.
Deshalb habe ich ein neues Projekt erstellt, um zu versuchen und bekommen ein funktionierendes Beispiel für die Abfrage, die ich will. Aber ich hatte das gleiche Problem, auch mit einem Barebone-test-Projekt.
Projekt ist mavenised, und die POM ist:
<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>
Ich habe eine TestEntity Klasse:
import java.util.Map;
import com.google.code.morphia.annotations.Entity;
@Entity
public class TestEntity {
Map<String, Integer> map;
}
Und endlich meine test-Klasse:
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);
}
}
Für mich, der obige code produziert nicht die richtige $und Abfrage, aber ich kann nicht sehen, warum
Du musst angemeldet sein, um einen Kommentar abzugeben.
Nur raten (habe keine Zeit zu testen), aber sollte es sein:
Update Du hast Recht,
Query.criteria
war nicht richtig--es war das, was war in der einfachen test, so dass ich dachte, du hättest etwas verpasst. Dies scheint zu funktionieren für mich (bricht es in zwei statements):Update 2 vollständiger test code:
gibt:
Query.criteria()
dauert nur einen string (das ist der name des Feldes), und beide arrays sind Listen vonCriteria
Objekte. Gibt es keine andere alternative Methoden zu benutzen, und da die übergabe der arrays gearbeitet, für den Bau einer einzelnen Klausel oder kann ich Sie brauchen, um check-out der Morphia-code und schreiben Sie ein test-Fall für dieses SzenarioTrotz Morphia 0.99 einschließlich der
Query.and(Criteria ...)
- Methode, generiert er nicht die richtige Abfrage.Thema 338, die Adressen Unterstützung für explizite $und - Klauseln in Abfragen gezielt an Morphia 0.99.1, die es derzeit nur als SNAPSHOT-version über Maven.
Jedoch mit 0.99.1-SNAPSHOT behoben das Problem für uns.
Query.and()
da die Aktualisierung der version. Vielleicht haben Sie fand einen sehr spezifischen Fall, wo es ein bug?