java - 嵌入列表中的 Morphia 查询

标签 java mongodb aggregation-framework 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;
.
.
.
}

我必须找到所有子 Activity 已过期的 Activity 。 我尝试使用

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

但它不起作用,因为还检索此 Activity

{
  "_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
    }]
}

其中子 Activity 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,它只允许等于比较,不允许其他条件比较。

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

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

关于java - 嵌入列表中的 Morphia 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40426773/

相关文章:

node.js - Mongoose 使用 presave 中间件推送到数组

node.js - 如何使用 Mongoose 和 NodeJS 将变量传递给聚合(匹配)?

java - 流在 for 循环中不起作用

java - 在 HashSet.contains() 如果 hashcode 返回常量值的情况下调用 hashCode() 和 equals() 的次数

java - 编写容器通用比较器的更好方法

java - 如何提高 Graphics2D 文本质量?

c# - 表达式树 mongodb linq 不支持 AsQueryable 方法

mongodb - 如何使用 docker-compose 和 docker-machine 为 mongoDB 挂载外部卷

mongodb - 获取mongodb中两个字段的最大差异

node.js - MongoDB 查询两个集合以添加/减去第一个集合中的字段与第二个集合中的匹配字段