2012-04-23 24 views
7

2 kriter listesi ve her birinde en az bir tane olmak üzere bir dizi koşul oluşturmak için Sorgu arabiriminin and() ve veya() yöntemlerini birleştirmeye çalışıyorum memnun olmalı.Morphia'da Karmaşık AND-OR sorgusu

Ben this discussion okudum ve iki $ veya cümleleri birleştirmek için Query.and() kullanmaya çalışıyorum.

Esasen, ben söylemeye çalışıyorum:

Criteria[] arrayA; 
Criteria[] arrayB; 

// Programatically populate both arrays 

Query q = dao.createQuery().and(
    q.or(arrayA), 
    q.or(arrayB) 
); 

Ben döngü vardır çünkü ihtiyacım belirli kriterleri oluşturmak için birkaç farklı girdilerin yoluyla kriterlerin dizileri kullanıyorum ve bu yaklaşım çalışır ben Ben sadece bir tek $ veya kullanıyorum, ama ben denedim ve $ ve cümleleri hem $ hem de yukarıda açıklandığı gibi denediğimde beklediğim sorguyu oluşturmak için Morphia alamıyorum. Ben $ ve sorgu yok ve ikinci $ veya ilk kez, sadece iki kez veya() iki kez yazmış gibi yazmış olduğunu buluyorum.

{ 
    "$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, 
     } 
    } 
} 

Ancak, ben sadece böyle bir sorgu olsun:

{ 
    "$or": { 
     "0": //Some other criteria, 
     "1": //Some other criteria, 
     "2": //Some other criteria, 
    } 
} 

Fazla belgelere bakın olamaz, ama şu an

Örneğin ben bir sorgu şu şekilde üretilebilir bekliyoruz Test vakası, bunun hakkında gitmek için doğru bir yol gibi görünüyor. Bu, neden beklediğim gibi çalışmadığı konusunda herhangi bir ışık tutabilir mi?

Düzenleme 0 (Bu soru Ben en iyi yanıt almak hangi bir yerde emin değilim gibi cross-posted to the Morphia mailing list idi):

Güncelleme: Bu tekrar baktığımda, Morfin test kodu dışarı kontrol ettikten ve her şey iyi çalışıyor, sorunumu test kodunda yeniden oluşturamadım.

Bu nedenle, istediğim sorgunun çalışan bir örneğini denemek için yeni bir proje oluşturdum. Ancak aynı sorunu, bir barebones test projesi ile bile karşılaştım. Benim için

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); 
    } 
} 

:

proje mavenised edilir ve POM geçerli:

import java.util.Map; 

import com.google.code.morphia.annotations.Entity; 

@Entity 
public class TestEntity { 
    Map<String, Integer> map; 
} 

Ve nihayet benim test sınıfını: Bir TestEntity sınıf var

<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> 

Yukarıdaki kod doğru $ ve sorgu üretmez, ancak neden göremiyorum

cevap

6

dahil Morfin 0.99 rağmen bu (iki ifadeleri içine kırarak) benim için iş gibi görünüyor Query.and(Criteria ...) yöntemi, doğru sorguyu oluşturmaz. açık $ ve sorgularda maddelere destek adresleri

Issue 338, Maven üzerinden ANLıK versiyonu olarak şu anda yalnızca Morfin 0.99.1, yöneliktir.

Ancak, 0,99,1-SNAPSHOT kullanarak sorunu çözdünüz.

+1

numaralı sorunu çözdü - son, çalışma örneğini vermek güzeldi. –

+0

Merhaba @RussBateman, kod değişmedi, 0.99.1-SNAPSHOT içinde çözülmüş olan 0.99 sürümünde bir sorun var gibi görünüyor, biz sadece kullandığımız kütüphanenin sürümünü değiştirdik (ideal değil, ama Biz en iyi seçenek vardı) – chrisbunney

+0

0.99.1-SNAPSHOT ile bile hala Query.and() ile ilgili bir sorunum var. Kriterler basit alanlar olduğu sürece tamamdır, ancak $ veya criterial değeri $ 'a dahil edildiğinde ve –

7

Sadece (test etmek için zaman yok) tahmin, ama bu olmalıdır: Haklısın

Query q = dao.createQuery().and(
    q.or(q.criteria(arrayA)), 
    q.or(q.criteria(arrayB)) 
); 

Update, Query.criteria doğru değildi - bu basit testte kullanılan buydu Bu yüzden bir şeyleri kaçırdığını düşündüm.

Query q = dao.createQuery(); 
q.and(
    q.or(arrayA), 
    q.or(arrayB) 
); 

Güncelleme 2 Daha tam test kodu:

Criteria[] arrayA = {dao.createQuery().criteria("test").equal(1), dao.createQuery().criteria("test").equal(3)}; 
Criteria[] arrayB = {dao.createQuery().criteria("test").equal(2), dao.createQuery().criteria("test").equal(4)};; 
Query q = dao.createQuery(); 
q.and(
    q.or(arrayA), 
    q.or(arrayB) 
); 
System.out.println(q.toString()); 

verir:

{ "$and" : [ { "$or" : [ { "test" : 1} , { "test" : 3}]} , { "$or" : [ { "test" : 2} , { "test" : 4}]}]} 
+0

Maalesef, 'Query.criteria()' olarak değil, yalnızca bir dize (alan adı) alır ve her iki dizide de "Kriter" nesnesinin listeleri vardır. Kullanmak için alternatif yöntemler yoktur ve dizilerin tek veya yan tümcesini oluşturmak için çalıştığı için Morphia kodunu kontrol etmem ve bu senaryo için bir test vakası yazmam gerekebilir – chrisbunney

+0

Daha iyi bir yanıtla güncellendi. Umarım senin için çalışır. –

+0

Güncelleme için teşekkürler, bu ilginç, bu yüzden böyle mi çalışıyor? Benim asıl sorgum, niyetimi göstermek için verdiğim basit örnekten daha karmaşıktır, ama prensibin sağlam olduğunu varsaydım. Belki de sorun sorgu kodunda başka bir yerdedir ve bu sadece belirtidir ... – chrisbunney