如何在 Java 中实现此 MongoDB 聚合
How do I implement this MongoDB aggregation in Java
我有以下工作 MongoDB 聚合 shell 命令:
db.followrequests.aggregate([{
$match: {
_id: ObjectId("551e78c6de5150da91c78ab9")
}
}, {
$unwind: "$requests"
}, {
$group: {
_id: "$_id",
count: {
$sum: 1
}
}
}]);
哪个returns:
{ "_id" : ObjectId("551e78c6de5150da91c78ab9"), "count" : 7 }
我需要在 Java 中实现它,我正在尝试以下操作:
List<DBObject> aggregationInput = new ArrayList<DBObject>();
BasicDBObject match = new BasicDBObject();
match.put("$match", new BasicDBObject().put("_id",new ObjectId(clientId)));
aggregationInput.add(match);
BasicDBObject unwind = new BasicDBObject();
unwind.put("$unwind", "$requests");
aggregationInput.add(unwind);
BasicDBObject groupVal = new BasicDBObject();
groupVal.put("_id", "$_id");
groupVal.put("count", new BasicDBObject().put("$sum", 1));
BasicDBObject group = new BasicDBObject();
group.put("$group", groupVal);
aggregationInput.add(group);
AggregationOutput output = followRequestsCol.aggregate(aggregationInput);
for (DBObject result : output.results()) {
System.out.println(result);
}
我遇到异常:
mongodb the match filter must be an expression in an object.
你能帮我找出上面代码中的错误吗?谢谢!
尝试打印 aggregationInput
的值,您会发现 .put()
不是 return 和 BasicDBObject
,而是与您更新的密钥关联的先前值.因此,当您这样做时:
match.put("$match", new BasicDBObject().put("_id",new ObjectId(clientId)));
您实际上是将 $match
设置为 null
,因为 new BasicDBObject().put("_id",new ObjectId(clientId))
returns null
.
将您的代码更新为:
List <DBObject> aggregationInput = new ArrayList <DBObject> ();
BasicDBObject match = new BasicDBObject();
BasicDBObject matchQuery = new BasicDBObject();
matchQuery.put("_id", new ObjectId());
match.put("$match", matchQuery);
aggregationInput.add(match);
BasicDBObject unwind = new BasicDBObject();
unwind.put("$unwind", "$requests");
aggregationInput.add(unwind);
BasicDBObject groupVal = new BasicDBObject();
groupVal.put("_id", "$_id");
groupVal.put("count", new BasicDBObject().put("$sum", 1));
BasicDBObject group = new BasicDBObject();
group.put("$group", groupVal);
aggregationInput.add(group);
AggregationOutput output = followRequestsCol.aggregate(aggregationInput);
for (DBObject result : output.results()) {
System.out.println(result);
}
或者,稍微更具可读性,使用流利的 BasicDBObjectBuilder
:
final DBObject match = BasicDBObjectBuilder.start()
.push("$match")
.add("_id", new ObjectId())
.get();
aggregationInput.add(match);
它应该可以正常工作。
每个 {}
必须是新的 DBObject
。也可以使用.append(key,value)
的方法来使更优雅。
试试这个:
List<DBObject> pipeline = new ArrayList<DBObject>(Arrays.asList(
new BasicDBObject("$match", new BasicDBObject("_id",
new ObjectId("551e78c6de5150da91c78ab9"))),
new BasicDBObject("$unwind", "$requests"),
new BasicDBObject("$group",
new BasicDBObject("_id","$_id").append("count", new BasicDBObject("$sum", 1)))));
AggregationOutput output = followRequestsCol.aggregate(pipeline);
for (DBObject result : output.results()) {
System.out.println(result);
}
这是最终的工作版本,基于以上建议
// 使用 mongodb 聚合框架来确定关注者的数量
整数 returnCount = 0;
列表 aggregationInput = new ArrayList();
BasicDBObject match = new BasicDBObject();
BasicDBObject matchQuery = new BasicDBObject();
matchQuery.put("_id", new ObjectId(clientId));
match.put("$match", matchQuery);
aggregationInput.add(match);
BasicDBObject unwind = new BasicDBObject();
unwind.put("$unwind", "$requests");
aggregationInput.add(unwind);
BasicDBObject groupVal = new BasicDBObject();
groupVal.put("_id", null);
BasicDBObject sum = new BasicDBObject();
sum.put("$sum", 1);
groupVal.put("count", sum);
BasicDBObject group = new BasicDBObject();
group.put("$group", groupVal);
aggregationInput.add(group);
AggregationOutput output = followRequestsCol.aggregate(aggregationInput);
for (DBObject result : output.results()) {
returnCount = (Integer) result.get("count");
break;
}
return returnCount;
我有以下工作 MongoDB 聚合 shell 命令:
db.followrequests.aggregate([{
$match: {
_id: ObjectId("551e78c6de5150da91c78ab9")
}
}, {
$unwind: "$requests"
}, {
$group: {
_id: "$_id",
count: {
$sum: 1
}
}
}]);
哪个returns:
{ "_id" : ObjectId("551e78c6de5150da91c78ab9"), "count" : 7 }
我需要在 Java 中实现它,我正在尝试以下操作:
List<DBObject> aggregationInput = new ArrayList<DBObject>();
BasicDBObject match = new BasicDBObject();
match.put("$match", new BasicDBObject().put("_id",new ObjectId(clientId)));
aggregationInput.add(match);
BasicDBObject unwind = new BasicDBObject();
unwind.put("$unwind", "$requests");
aggregationInput.add(unwind);
BasicDBObject groupVal = new BasicDBObject();
groupVal.put("_id", "$_id");
groupVal.put("count", new BasicDBObject().put("$sum", 1));
BasicDBObject group = new BasicDBObject();
group.put("$group", groupVal);
aggregationInput.add(group);
AggregationOutput output = followRequestsCol.aggregate(aggregationInput);
for (DBObject result : output.results()) {
System.out.println(result);
}
我遇到异常:
mongodb the match filter must be an expression in an object.
你能帮我找出上面代码中的错误吗?谢谢!
尝试打印 aggregationInput
的值,您会发现 .put()
不是 return 和 BasicDBObject
,而是与您更新的密钥关联的先前值.因此,当您这样做时:
match.put("$match", new BasicDBObject().put("_id",new ObjectId(clientId)));
您实际上是将 $match
设置为 null
,因为 new BasicDBObject().put("_id",new ObjectId(clientId))
returns null
.
将您的代码更新为:
List <DBObject> aggregationInput = new ArrayList <DBObject> ();
BasicDBObject match = new BasicDBObject();
BasicDBObject matchQuery = new BasicDBObject();
matchQuery.put("_id", new ObjectId());
match.put("$match", matchQuery);
aggregationInput.add(match);
BasicDBObject unwind = new BasicDBObject();
unwind.put("$unwind", "$requests");
aggregationInput.add(unwind);
BasicDBObject groupVal = new BasicDBObject();
groupVal.put("_id", "$_id");
groupVal.put("count", new BasicDBObject().put("$sum", 1));
BasicDBObject group = new BasicDBObject();
group.put("$group", groupVal);
aggregationInput.add(group);
AggregationOutput output = followRequestsCol.aggregate(aggregationInput);
for (DBObject result : output.results()) {
System.out.println(result);
}
或者,稍微更具可读性,使用流利的 BasicDBObjectBuilder
:
final DBObject match = BasicDBObjectBuilder.start()
.push("$match")
.add("_id", new ObjectId())
.get();
aggregationInput.add(match);
它应该可以正常工作。
每个 {}
必须是新的 DBObject
。也可以使用.append(key,value)
的方法来使更优雅。
试试这个:
List<DBObject> pipeline = new ArrayList<DBObject>(Arrays.asList(
new BasicDBObject("$match", new BasicDBObject("_id",
new ObjectId("551e78c6de5150da91c78ab9"))),
new BasicDBObject("$unwind", "$requests"),
new BasicDBObject("$group",
new BasicDBObject("_id","$_id").append("count", new BasicDBObject("$sum", 1)))));
AggregationOutput output = followRequestsCol.aggregate(pipeline);
for (DBObject result : output.results()) {
System.out.println(result);
}
这是最终的工作版本,基于以上建议 // 使用 mongodb 聚合框架来确定关注者的数量 整数 returnCount = 0; 列表 aggregationInput = new ArrayList();
BasicDBObject match = new BasicDBObject();
BasicDBObject matchQuery = new BasicDBObject();
matchQuery.put("_id", new ObjectId(clientId));
match.put("$match", matchQuery);
aggregationInput.add(match);
BasicDBObject unwind = new BasicDBObject();
unwind.put("$unwind", "$requests");
aggregationInput.add(unwind);
BasicDBObject groupVal = new BasicDBObject();
groupVal.put("_id", null);
BasicDBObject sum = new BasicDBObject();
sum.put("$sum", 1);
groupVal.put("count", sum);
BasicDBObject group = new BasicDBObject();
group.put("$group", groupVal);
aggregationInput.add(group);
AggregationOutput output = followRequestsCol.aggregate(aggregationInput);
for (DBObject result : output.results()) {
returnCount = (Integer) result.get("count");
break;
}
return returnCount;