0

morphia POJO マッパーを使用して mongodb にフィルターを実装しているときに、いくつかの問題があります。

私のクラス (たとえばSampleClass) で、クラスのフィールド@Entity(この場合はPerson) にアクセスしようとすると、int、string、maps、直接埋め込みオブジェクトなどの一般的なフィールドにドット表記を使用して、フィールド アクセスが正常に機能することがわかりました。

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

たとえば、リストにstreetNameあるAddressオブジェクトにフィルターを適用したい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() );
    }
}

リスト内のオブジェクトにアクセスしているときに何か間違ったことをしていますか?

4

3 に答える 3

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

よろしく、悲しい

于 2012-05-24T09:11:51.183 に答える
1

実際に試したクエリはaddresses、フィールドを持つサブドキュメントをクエリしますstreetname。したがって、アドレスのリストではなく、具体的なアドレスとしてアドレスを持つドキュメントのみが取得されます。一致するアドレスを少なくとも 1 つ含むすべての人に一致させるには、$elemMatch http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-ValueinanArrayを使用します。しかし、あなたのスキーマで Morphia がそのようなクエリを実行できるかどうかはわかりません。実際のドキュメントにはこれらのアドレスが埋め込まれているわけではなく、dbref http://www.mongodb.org/display/DOCS/Database+Referencesのみが含まれていることに注意してください。そのため、mongoDB は DBRef をまったく認識しないため (これは一部のドライバー規則にすぎないため)、morphia がクエリを変換するほどスマートでない場合、クエリは成功しません。

したがって、morphia がこの機能を提供しない場合は、別のクエリを実行する必要があります。最初に、条件に一致するアドレスの Addresses コレクションをクエリする必要があります。これらの ObjectId を収集し、Person Collection クエリ$elemMatchと一緒に使用して$in、そのようなアドレスを持たないすべての人物と、追加のフィルター オプションを除外します。結合を行うリレーショナル システムがないことに注意する必要があります。

于 2012-05-24T07:59:26.060 に答える
0

それは私にとってtyopのように見えますcontainer.add( query.criteria( "addresses.streetname").containsIgnoreCase( "mainstreet" ) );

streetnameに変更する必要があると思いますstreetName

モルフィアを使い始めて1年。私の知る限り、container.add( query.criteria( "addresses.streetName").containsIgnoreCase( "mainstreet" ) );うまくいくはずです。

于 2012-05-29T19:08:33.383 に答える