嵌入式列表中的 Morphia 查询
Morphia query in embedded list
我的问题是查询复杂元素。
@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)
);
但它不起作用,因为还检索了这个 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
}]
}
其中 sub 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,只能进行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);
我的问题是查询复杂元素。
@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)
);
但它不起作用,因为还检索了这个 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
}]
}
其中 sub 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,只能进行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);