通过mongodb中的morphia对类中对象列表进行字段访问

时间:2012-05-23 15:36:09

标签: mongodb entity field morphia

使用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() );
    }
}

访问列表中的对象时我做错了吗?

3 个答案:

答案 0 :(得分:5)

“addresses”字段是@Reference,我们不能将“addresses.name”用作条件中的字段。它应该是地址字段位于“List&lt; Key&lt; Address&gt;&gt;”中的标准。 :

    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

答案 1 :(得分:1)

您实际尝试的查询将使用字段addresses查询子文档streetname。因此,您只能获得具有地址作为具体地址而不是地址列表的文档。要匹配包含至少一个地址匹配的所有人,请使用$elemMatch http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-ValueinanArray。 但我不确定如果Morphia能够使用您的架构执行此类查询。请记住,您的实际文档不包含嵌入的地址,而是仅包含dbrefs http://www.mongodb.org/display/DOCS/Database+References。因此,如果morphia不够智能转换您的查询,它就不会成功,因为mongoDB根本不知道DBRef(因为这只是一些驱动程序约定)。

因此,对于morphia不提供此功能的情况,您需要查询不同的内容。首先,您需要查询您的地址集合,以查找符合您条件的地址。收集这些ObjectIds并在Person Collection查询中将其与$elemMatch$in一起使用,以过滤掉所有没有此类地址的人,以及您的其他过滤选项。你需要记住,你没有一些为你加入的关系系统。

答案 2 :(得分:0)

它看起来像我的container.add( query.criteria( "addresses.streetname").containsIgnoreCase( "mainstreet" ) );

我认为streetname需要更改为streetName

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