2016-11-04 58 views
0

我的问题是查询一个复杂的元素。Morphia查询嵌入式列表

@Entity("Activity") 
public class Activity extends BaseEntity { 
     private String name; 
     private String description; 
     private Date deadline; 
     private Boolean completed; 
     @Embedded 
     private List<SubActivity> listSubActivity; 
    . 
    . 
    . 
} 

其中

@Entity("SubActivity") 
public class SubActivity extends BaseEntity { 
    private String name; 
    private Date deadline; 
    private Boolean completed; 
. 
. 
. 
} 

我必须找到与子活动的所有活动过期。 我尝试用

Query<Activity> queryA = datastore.createQuery(Activity.class); 
queryA.and(
    queryA.criteria("deadline").lessThan(today), // where today is a Date() 
    queryA.criteria("completed").equal(false) 
); 

,但它不工作,因为还检索该活动

{ 
    "_id" : ObjectId("581352597dfd063decb0b357"), 
    "className" : "com.etherweaver.collections.Activity", 
    "name" : "Name", 
    "description" : "description", 
    "deadline" : ISODate("2016-11-02T23:00:00.000Z"), 
    "completed" : true, 
    "listSubActivity" : [{ 
     "name" : "sub activity 1", 
     "deadline" : ISODate("2016-11-01T23:00:00.000Z"), 
     "completed" : true 
    }, { 
     "name" : "sub activity 2", 
     "deadline" : ISODate("2016-11-06T23:00:00.000Z"), 
     "completed" : false 
    }, { 
     "name" : "sub activity 3", 
     "deadline" : ISODate("2016-11-06T23:00:00.000Z"), 
     "completed" : true 
    }] 
} 

其中子活动1已过期,但完成。

是否有一种方法来查询嵌入了逐行验证条件的列表?

回答

0

你可以尝试下面的东西。

Query<SubActivity> query = datastore.createQuery(SubActivity.class) 
     .filter("deadline < ", new Date()) 
     .filter("completed = ", true); 

List<Activity> activities = datastore.find(Activity.class) 
               .field("listSubActivity") 
               .elemMatch(query) 
               .asList(); 

更新

要使用hasThisElement,只允许等于比较没有其他条件比较。

所以我不确定这是否会为你工作,但对不起,我现在没有看到任何其他的方式。

SubActivity filter = new SubActivity(); 
filter.setDeadline(new Date()); 
filter.setCompleted(true); 

List<Activity> activities = datastore.find(Activity.class) 
               .field("listSubActivity") 
               .hasThisElement(filter) 
               .asList(); 

更新2

聚合为基础的方法 - 这种方法将过滤基于查询的行。

import static org.mongodb.morphia.aggregation.Group.*; 

Query<Activity> query = datastore.createQuery(Activity.class) 
       .filter("listSubActivity.deadline < ", anyDate) 
       .filter("listSubActivity.completed = ", true); 

Iterator<Activity> activities = datastore.createAggregation(Activity.class). 
       unwind("listSubActivity"). 
       match(query). 
       group("_id", grouping("className", first("className")), 
         grouping("name", first("name")), 
         grouping("description", first("description")), 
         grouping("deadline", first("deadline")), 
         grouping("completed", first("completed")), grouping("listSubActivity", push("listSubActivity"))).aggregate(Activity.class); 
+0

_.elemMatch(query)_不存在的方法 – Giampaolo

+0

elemMatch在快照版本中有。更新为使用hasThisElement。现在无法测试它。希望它有帮助 – Veeram

+0

谢谢,我想这是正确的方法,但方法_hasThisElement_需要一个对象,而不是查询。 – Giampaolo