2012-05-23 4 views
0

mongodb에서 morphia POJO 매퍼를 사용하여 필터를 구현하는 동안 몇 가지 문제가 있습니다. 내가 @Entity 클래스의 필드에 액세스하려고 할 때 내 수업에서 mongodb의 morphia를 통해 클래스의 객체 목록에 대한 필드 액세스

(예 SampleClass 용), (우리의 경우는 Person는 것), I 필드 액세스 INT, 문자열 같은 일반적인 필드 점 표기법을 사용하여, 잘 작동 찾기 ,지도 또는 직접 임베디드 개체.

문제는 Person 클래스에서 참조되는 "List of Objects"의 경우에 어떻게 작동하는지 이해할 수 없습니다.

@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에 필터를 적용 할 (이 Person 클래스는 Address 개체의 목록을 보유하고 필드 addresses을 가지고, 그래서 사람이 많은 주소를 가질 수 있습니다, 여기에 가정)하는 목록의 개체에 액세스하는 동안 내가 뭔가 잘못하고있는 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

실제로 시도한 쿼리 하위 필드를 streetname 쿼리합니다. 따라서 주소가 아닌 구체적인 주소로 된 문서 만 가져올 수 있습니다. 일치하는 주소가 하나 이상있는 모든 사람을 일치 시키려면 $elemMatchhttp://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-ValueinanArray을 사용하십시오. 그러나 Morphia가 스키마와 함께 이러한 쿼리를 수행 할 수 있는지 확실하지 않습니다. 실제 문서에는 포함 된 주소가 포함되어 있지 않으며 대신 dbrefs http://www.mongodb.org/display/DOCS/Database+References 만 포함됩니다. 따라서 morphia가 쿼리를 변환 할만큼 똑똑하지 않으면 mongoDB가 DBRef를 전혀 알지 못하기 때문에 성공하지 못합니다 (이는 일부 드라이버 규칙이므로).

morphia는이 기능을 제공하지 않으므로 다른 검색어를 사용해야합니다. 먼저 주소 컬렉션에 조건에 맞는 주소를 쿼리해야합니다. 해당 ObjectId를 수집하고 Person Collection 쿼리에서 $elemMatch$in과 함께 사용하여 이러한 주소가없는 모든 사용자를 필터링하고 추가 필터 옵션을 필터링하십시오. 당신은 당신을 위해 합류하는 관계형 시스템을 가지고 있지 않다는 것을 명심해야합니다.

+0

답장을 보내 주셔서 감사합니다. 해결책을 찾았습니다. 나는 그것을 여기 게시 할 것이다 –

+0

나는이 문제에 의심이있다. 이 필드를 ** @ Transient ** ** @ Reference **리스트로 만들면

addresses = new ArrayList
; -> 그런 다음 동일한 솔루션을 적용 할 수 있습니까?일시적인 (db로 저장된 nt)이기 때문에 속성 주소를 찾을 수 없다는 문제점이 있습니다. 그러면 우리는 어떻게 이런 분야를 가지고 놀 수 있을까요? 그것은 저장되었습니다,하지만이 필드를 사용하여 쿼리를 해결하고 싶습니다. 이것에 관한 어떤 생각? 감사! –

+0

임시로 저장하는 모든 것은 임시로 필요한 정보 만 고려해야합니다 (대부분 큰 값이 아닙니다). 그래서 기본적으로 일시적인 필드를 사용하여 수행하는 작업은 다른 비 일시적인 필드에서 런타임으로 일부 계산 된 값을 제공하는 것입니다. 쿼리 할 때 이러한 정보가 필요하면 mongo에 저장하는 것이 좋습니다. 왜 그걸 일시적으로 유지하고 싶지 않습니까? 그 뒤에있는 비즈니스 논리는 무엇입니까? 런타임에 사람/주소 연결이 필요하고 지속되지 않는 이유는 무엇입니까? – philnate

5

"주소"필드는 @Reference입니다. 우리는 "주소 .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()); 

관련,

+0

귀하는 수락 한 답변을 수락 할 수 있습니다. – philnate

+0

널 포인터 예외가 발생했습니다! @Sadish – Milson

0

그 날 container.add(query.criteria("addresses.streetname").containsIgnoreCase("mainstreet"));에 대한 tyop처럼 보이는 sadish : 그것은 주소 필드가에서 "목록 < 키 < 주소>>"하는 기준이되어야한다.

streetnamestreetName으로 변경해야한다고 생각합니다.

나는 1 년 동안 모르 피아를 사용 해왔다. AFAIK, container.add(query.criteria("addresses.streetName").containsIgnoreCase("mainstreet")); 잘 작동합니다.