【问题标题】:Morphia query in embedded list嵌入式列表中的 Morphia 查询
【发布时间】:2016-11-04 15:46:56
【问题描述】:

我的问题是查询一个复杂的元素。

@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 已过期但已完成。

有没有办法逐行查询嵌入条件验证的列表?

【问题讨论】:

    标签: java mongodb aggregation-framework morphia


    【解决方案1】:

    你可以试试下面的方法。

    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,它只允许equals比较,不能进行其他条件比较。

    所以我不确定这是否适合你,但很抱歉,我现在看不到任何其他方法。

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

    【讨论】:

    • 方法.elemMatch(query)不存在
    • elemMatch 存在于快照版本中。更新为使用 hasThisElement。暂时不能测试。希望对你有帮助
    • 谢谢,我想这是正确的方法,但是方法 hasThisElement 需要一个对象,而不是查询。
    • 好的,这很好,但我需要找到所有过期的子活动。 filter.setDeadline(new Date()); 让我找到在特定日期过期的子活动,而不是所有在今天之前。
    • 根据反馈更新。希望对您有所帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-05-18
    • 2022-10-21
    • 1970-01-01
    • 1970-01-01
    • 2016-07-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多