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”用作条件中的字段。它应该是地址字段在 "List< Key< Address >>" 中的条件:

    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。因此,您只会获得地址为具体地址而不是地址列表的文档。要匹配包含至少一个地址匹配的所有人员,请使用$elemMatch http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-ValueinanArray。但我不确定 Morphia 是否能够使用您的模式执行此类查询。请记住,您的实际 Document 不包含嵌入的这些地址,而是仅包含 dbrefs http://www.mongodb.org/display/DOCS/Database+References。因此,如果 morphia 不够聪明,无法转换您的查询,它将不会成功,因为 mongoDB 根本不知道 DBRefs(因为这只是一些驱动程序约定)。

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

于 2012-05-24T07:59:26.060 回答
0

对我来说它看起来像打字错误container.add( query.criteria( "addresses.streetname").containsIgnoreCase( "mainstreet" ) );

我认为streetname需要更改为streetName.

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

于 2012-05-29T19:08:33.383 回答