2012-05-23 34 views
0

我在使用morphia POJO映射器在mongodb中實現過濾器時遇到一些問題。在mongodb中通過morphia實現類中對象列表的字段訪問

在我的類(例如SampleClass),當我嘗試訪問@Entity類的字段(在我們的情況下,它Person),我發現現場訪問工作正常,使用點符號爲如int,字符串一般領域,地圖或直接嵌入的對象。

問題是我無法理解它如何在Person類中引用的「對象列表」的情況下工作。 (這裏假設,一個人可以有多個地址,所以這個Person類有一個場addresses持有Address對象的列表)

@Entity 
Class Person 
{ 
    String name; 
    int age; 
    String type; 
    private Map<String, String> personalInfo= new HashMap<String, String>(); 
    @Reference 
    List<Address> addresses = new ArrayList<Address>; 
} 

@Entity 
Class Address 
{ 
    String streetName; 
    int doorNo; 
} 

例如,我想在Address對象的streetName應用過濾器在addresses列表

public class SampleClass 
{ 
    private Datastore ds; 
    Query<Node>    query; 
    CriteriaContainer  container; 

    // connections params etc.... 
    public List<Person> sampleMethod() 
    { 
     query = ds.find(Person.class).field("type").equal("GOOD");        

     container.add(query.criteria("name").containsIgnoreCase("jo")); 
     // general String field in the Person Class ---- OKAY, Work's Fine 

     container.add(query.criteria("personalInfo.telephone").containsIgnoreCase("458")); 
     // Map field in the Person Class, accessing telephone key value in the map --- OKAY, Work's Fine 

     container.add(query.criteria("addresses.streetname").containsIgnoreCase("mainstreet")); 
     // List of address object in the Person Class, name of the field is 'addresses' 
     // ----NOT OKAY ????????? -- Here is the problem it returns nothing, even though some value exists 

     return readTopography(query.asList()); 
    } 
} 

我在做訪問列表中的對象時出錯嗎?

回答

1

您實際嘗試的查詢將查詢子字段addresses,字段爲streetname。所以你只能得到具有地址作爲具體地址而不是地址列表的文件。要匹配所有包含至少一個匹配地址的人員,請使用$elemMatchhttp://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-ValueinanArray。 但我不確定如果Morphia能夠執行這樣的查詢,根本就不需要你的模式。請記住,實際的文檔不包含嵌入的地址,而只包含dbrefs http://www.mongodb.org/display/DOCS/Database+References。所以如果morphia不夠聰明來轉換你的查詢,它將不會成功,因爲mongoDB根本不知道DBRefs(因爲這只是一些驅動程序約定)。

因此,對於morphia不提供此功能您需要查詢不同的情況。首先,您需要查詢您的地址集合以查找符合您的條件的地址。收集這些ObjectIds並將其與$elemMatch$in一起用於Person Collection查詢,以篩選出沒有此地址的所有人以及您的其他過濾器選項。你需要記住,你沒有一些關係系統爲你加入。

+0

感謝您的回覆。我找到了解決方案。我會在這裏發帖 –

+0

我對這個問題有疑問,如果我將此字段設爲** @ Transient ** ** @參考**列表

addresses = new ArrayList
; - >那我可以應用相同的解決方案嗎?我發現它無法找到屬性地址,因爲它是暫時的(nt保存在數據庫中)。那麼我們該如何玩這樣的領域呢?它沒有保存,但我想解析使用此字段的查詢。有關這個的任何想法?謝謝! –

+0

您存儲爲瞬態的所有內容都必須被認爲只是暫時需要的信息(並且大部分沒有大的值)。所以基本上你對瞬態場的處理就是提供一些計算值作爲運行時間,超出其他非瞬態場。如果你需要這樣的信息來查詢,那麼他們不會將它們存儲在mongo中。 爲什麼你希望這是暫時的,而不是持續,你的業務邏輯是什麼? 爲什麼只有在運行時才需要人員/地址連接並且不會持續? – philnate

5

「addresses」字段是@Reference,我們不能使用「addresses.name」作爲條件中的字段。這應該是一個標準,如果地址字段是 「列表<主要<地址>>」:

Query<Person> personQuery = ds.createQuery(Person.class); 
    Query<Address> addressQuery = ds.createQuery(Address.class); 
    addressQuery.criteria("streetName").containsIgnoreCase("mainstreet"); 
    container.add(personQuery.criteria("addresses").in(addressQuery.asKeyList())); 

    System.out.println(personQuery.asList()); 

問候, sadish

+0

你可以接受你自己的答案作爲接受的答案。 – philnate

+0

我得到了空指針異常! @Sadish – Milson

0

它看起來像tyop我container.add(query.criteria("addresses.streetname").containsIgnoreCase("mainstreet"));。我想streetname需要更改爲streetName

我一直在使用嗎啡一年了。 AFAIK,container.add(query.criteria("addresses.streetName").containsIgnoreCase("mainstreet"));應該可以正常工作。

相關問題