如何在JavaSpring的mongoTemplate聚合中实现$SetIsSubset?
How to implement $SetIsSubset in mongoTemplate aggregation of Java Spring?
我正在尝试在 mongoTemplate 聚合中使用 $setIsSubset class。但是找不到任何解决方案。
我的Mongo查询是:
db.events.aggregate([
{ $match: { $and: [
{ "event_state" : {$in : ["live","scheduled"]} },
{ "schedule.end_time" : {$gt : ISODate("2016-12-12T06:30:00.000Z")} }
]
}
},
{$project:
{
"name" :1,
"category" :1,
"schedule":1,
"celebrity" :1,
"online_moderator" :1,
"offline_moderator" :1,
"region" :1,
"status" :1,
"event_state" :1,
"recorder_id" :1,
"webcast_url":1,
"replay_url":1,
"registered_users":1,
registeredUsers: { $size:"$registered_users" },
is_registered:
{ $setIsSubset: [[ObjectId("584e6253e17ed10f0a8cba1d"),ObjectId("583e9719e17e8c1bf80da2fe")], "$registered_users.user_id"]}
}
},
{ $sort : {
"schedule.start_time": 1
}
}
]);
我已经转换了大部分代码,如下所示。但是遇到了 $setIsSubset 条件。
matchCondition = Aggregation.match(Criteria.where("event_state")
.in(listEventStates).and("schedule.end_time").gt(d));
AggregationOperation projectValues = Aggregation.project()
.and("registered_users").size().as("registered_users_count")
.and("name").as("name").and("category").as("category")
.and("schedule").as("schedule").and("online_moderator")
.as("online_moderator").and("offline_moderator")
.as("offline_moderator").and("region").as("region")
.and("status").as("status").and("event_state")
.as("event_state").and("recorder_id").as("recorder_id")
.and("webcast_url").as("webcast_url").and("replay_url")
.as("replay_url");
sortCondition = Aggregation.sort(Sort.Direction.ASC,
"schedule.start_time");
Aggregation aggrigation = Aggregation.newAggregation(matchCondition,
sortCondition, projectValues);
编辑:
根据@user_531 的要求。我正在用对我有用的可能解决方案更新我的问题。我不知道它是否会起作用,因为我使用该解决方案已经 2 年了。之后又改了几次代码,就不再维护这个项目了。但值得一试。
AggregationOperation projectValues = Aggregation.project().and("registered_users").size()
.as("registered_users_count").and("event_image").as("event_image")
.and("name").as("name").and("category").as("category").and("schedule").as("schedule")
.and("region").as("region").and("status").as("status").and("event_state").as("event_state")
.and("recorder_id").as("recorder_id").and("webcast_url").as("webcast_url").and("replay_url")
.as("replay_url").and("registered_users").as("registered_users").and("room_details").as("room_details")
.and("live_stream_url").as("live_stream_url")
.and(new AggregationExpression() {
public DBObject toDbObject(AggregationOperationContext context) {
return new BasicDBObject("$setIsSubset", Arrays.<Object> asList(
Arrays.<Object> asList(new ObjectId("58528314e17edbb252692815")),
"$registered_users.user_id"));
}
}).as("is_registered");
Aggregation aggrigation = Aggregation.newAggregation(matchCondition, sortCondition, projectValues);
AggregationResults<Events> results = mongoTemplate.aggregate(aggrigation, "events", Events.class);
您可以使用 Mongodb api 用于项目 (com.mongodb.client.model.Aggregates.project) 也可以用于匹配 (com.mongodb.client.model.Aggregates.match(Bson 过滤器))
您可以使用我刚刚完成的代码,例如使用 $setIsSubset
使用此查询
db.getCollection('collection').aggregate(
{ $match : {"_id" : "dff26f9c-350b-4bd5-bc62-62c19f21100c"} },
{ "$project": {
"sensorId": 1, "sensorModel": 1,
"attachments": {
"$filter": {
"input": "$attachments",
"as": "attachment",
"cond": {
"$setIsSubset": [
["$$attachment.type"],
["StructAttachment", "BlobAttachment"]
]
} } } }})
java 代码如下:
List <Bson> aggregationInput = new ArrayList <Bson> ();
aggregationInput.add(match(eq("_id",id)));
HashMap<String, Integer> fieldsMap=new HashMap<String, Integer>();
fieldsMap.put("sensorId", 1);
fieldsMap.put("sensorModel", 1);
ArrayList< ArrayList<String>> isSubset = new ArrayList< ArrayList<String>>();
ArrayList<String> isSubsetParameter1 = new ArrayList<String>();
isSubsetParameter1.add("$$attachment.mimeType");
ArrayList<String> isSubsetParameter2 = new ArrayList<String>();
isSubset.add(isSubsetParameter1 );
isSubset.add(isSubsetParameter2 );
Document docFields = new Document();
if (mimeTypes == null || mimeTypes.isEmpty()) {
//mimeTypes是一个Set
isSubsetParameter2.addAll(mimeTypes);
Document filter = new Document();
filter.put("input", "$attachments");
filter.put("as", "attachment");
filter.put("cond", new Document("$setIsSubset", isSubset));
docFields.put("attachments", new Document("$filter",filter));
docFields.putAll(fieldsMap);
aggregationInput.add(project(docFields));
AggregateIterable<Document> resultIteratr = mongo.getDatabase("db").getCollection("collection")
.aggregate(aggregationInput);
希望这对你有用!
利用AggressionExpression
。在项目中包含以下投影。使用1.8.5springmongo数据版本
and(new AggregationExpression() {
@Override
public DBObject toDbObject(AggregationOperationContext context) {
return new BasicDBObject("$setIsSubset",
Arrays.<Object> asList(
Arrays.<Object> asList("584e6253e17ed10f0a8cba1d",
"583e9719e17e8c1bf80da2fe"),
"$registered_users.user_id"));
}
}).as("is_registered"));
您可以将表达式包装为 Java 8
的 lambda
and(context -> new BasicDBObject("$setIsSubset",
Arrays.<Object> asList(
Arrays.<Object> asList("584e6253e17ed10f0a8cba1d",
"583e9719e17e8c1bf80da2fe"),
"$registered_users.user_id")))
.as("is_registered"));
我正在尝试在 mongoTemplate 聚合中使用 $setIsSubset class。但是找不到任何解决方案。
我的Mongo查询是:
db.events.aggregate([
{ $match: { $and: [
{ "event_state" : {$in : ["live","scheduled"]} },
{ "schedule.end_time" : {$gt : ISODate("2016-12-12T06:30:00.000Z")} }
]
}
},
{$project:
{
"name" :1,
"category" :1,
"schedule":1,
"celebrity" :1,
"online_moderator" :1,
"offline_moderator" :1,
"region" :1,
"status" :1,
"event_state" :1,
"recorder_id" :1,
"webcast_url":1,
"replay_url":1,
"registered_users":1,
registeredUsers: { $size:"$registered_users" },
is_registered:
{ $setIsSubset: [[ObjectId("584e6253e17ed10f0a8cba1d"),ObjectId("583e9719e17e8c1bf80da2fe")], "$registered_users.user_id"]}
}
},
{ $sort : {
"schedule.start_time": 1
}
}
]);
我已经转换了大部分代码,如下所示。但是遇到了 $setIsSubset 条件。
matchCondition = Aggregation.match(Criteria.where("event_state")
.in(listEventStates).and("schedule.end_time").gt(d));
AggregationOperation projectValues = Aggregation.project()
.and("registered_users").size().as("registered_users_count")
.and("name").as("name").and("category").as("category")
.and("schedule").as("schedule").and("online_moderator")
.as("online_moderator").and("offline_moderator")
.as("offline_moderator").and("region").as("region")
.and("status").as("status").and("event_state")
.as("event_state").and("recorder_id").as("recorder_id")
.and("webcast_url").as("webcast_url").and("replay_url")
.as("replay_url");
sortCondition = Aggregation.sort(Sort.Direction.ASC,
"schedule.start_time");
Aggregation aggrigation = Aggregation.newAggregation(matchCondition,
sortCondition, projectValues);
编辑:
根据@user_531 的要求。我正在用对我有用的可能解决方案更新我的问题。我不知道它是否会起作用,因为我使用该解决方案已经 2 年了。之后又改了几次代码,就不再维护这个项目了。但值得一试。
AggregationOperation projectValues = Aggregation.project().and("registered_users").size()
.as("registered_users_count").and("event_image").as("event_image")
.and("name").as("name").and("category").as("category").and("schedule").as("schedule")
.and("region").as("region").and("status").as("status").and("event_state").as("event_state")
.and("recorder_id").as("recorder_id").and("webcast_url").as("webcast_url").and("replay_url")
.as("replay_url").and("registered_users").as("registered_users").and("room_details").as("room_details")
.and("live_stream_url").as("live_stream_url")
.and(new AggregationExpression() {
public DBObject toDbObject(AggregationOperationContext context) {
return new BasicDBObject("$setIsSubset", Arrays.<Object> asList(
Arrays.<Object> asList(new ObjectId("58528314e17edbb252692815")),
"$registered_users.user_id"));
}
}).as("is_registered");
Aggregation aggrigation = Aggregation.newAggregation(matchCondition, sortCondition, projectValues);
AggregationResults<Events> results = mongoTemplate.aggregate(aggrigation, "events", Events.class);
您可以使用 Mongodb api 用于项目 (com.mongodb.client.model.Aggregates.project) 也可以用于匹配 (com.mongodb.client.model.Aggregates.match(Bson 过滤器)) 您可以使用我刚刚完成的代码,例如使用 $setIsSubset
使用此查询
db.getCollection('collection').aggregate(
{ $match : {"_id" : "dff26f9c-350b-4bd5-bc62-62c19f21100c"} },
{ "$project": {
"sensorId": 1, "sensorModel": 1,
"attachments": {
"$filter": {
"input": "$attachments",
"as": "attachment",
"cond": {
"$setIsSubset": [
["$$attachment.type"],
["StructAttachment", "BlobAttachment"]
]
} } } }})
java 代码如下:
List <Bson> aggregationInput = new ArrayList <Bson> ();
aggregationInput.add(match(eq("_id",id)));
HashMap<String, Integer> fieldsMap=new HashMap<String, Integer>();
fieldsMap.put("sensorId", 1);
fieldsMap.put("sensorModel", 1);
ArrayList< ArrayList<String>> isSubset = new ArrayList< ArrayList<String>>();
ArrayList<String> isSubsetParameter1 = new ArrayList<String>();
isSubsetParameter1.add("$$attachment.mimeType");
ArrayList<String> isSubsetParameter2 = new ArrayList<String>();
isSubset.add(isSubsetParameter1 );
isSubset.add(isSubsetParameter2 );
Document docFields = new Document();
if (mimeTypes == null || mimeTypes.isEmpty()) {
//mimeTypes是一个Set isSubsetParameter2.addAll(mimeTypes);
Document filter = new Document();
filter.put("input", "$attachments");
filter.put("as", "attachment");
filter.put("cond", new Document("$setIsSubset", isSubset));
docFields.put("attachments", new Document("$filter",filter));
docFields.putAll(fieldsMap);
aggregationInput.add(project(docFields));
AggregateIterable<Document> resultIteratr = mongo.getDatabase("db").getCollection("collection")
.aggregate(aggregationInput);
希望这对你有用!
利用AggressionExpression
。在项目中包含以下投影。使用1.8.5springmongo数据版本
and(new AggregationExpression() {
@Override
public DBObject toDbObject(AggregationOperationContext context) {
return new BasicDBObject("$setIsSubset",
Arrays.<Object> asList(
Arrays.<Object> asList("584e6253e17ed10f0a8cba1d",
"583e9719e17e8c1bf80da2fe"),
"$registered_users.user_id"));
}
}).as("is_registered"));
您可以将表达式包装为 Java 8
的 lambdaand(context -> new BasicDBObject("$setIsSubset",
Arrays.<Object> asList(
Arrays.<Object> asList("584e6253e17ed10f0a8cba1d",
"583e9719e17e8c1bf80da2fe"),
"$registered_users.user_id")))
.as("is_registered"));