Srping集合MongoDB
地址:http://blog.csdn.net/bicheng4769/article/details/79626382
Spring中如何使用Aggregate聚合函数
- 原始数据:
{
"_id" : ObjectId("5aab3460353df3bd352e0e15"),
"addTime" : ISODate("2018-03-16T03:05:04.363Z"),
"tag" : "test",
"userInfo" : [
{
"name" : "cj",
"address" : "江苏",
"age" : 24.0,
"userTag" : "stu"
},
{
"name" : "hj",
"address" : "江苏",
"age" : 26.0,
"userTag" : "stu"
},
{
"name" : "lbl",
"address" : "美国",
"age" : 22.0,
"userTag" : "teach"
}
]
}
- 查询语句:
db.test.aggregate([{"$unwind":"$userInfo"},
{"$match":{"userInfo.userTag":"stu","tag":"test"}},
{"$project":{"userInfo":1}}])
- spring中使用aggregate函数:
spring-mongodb 所有对mongodb的操作都是通过mongoTemplate
这个类来进行增删改查。我们这里只是介绍使用aggregate这个函数的使用方法,其他的操作可以参考文档
官方文档地址:
https://docs.spring.io/spring-data/mongodb/docs/2.0.5.RELEASE/reference/html/
有关aggregate的相关文档也可以参考(也就是上面文档的第九章)
https://docs.spring.io/spring-data/mongodb/docs/2.0.5.RELEASE/reference/html/#mongo.aggregation
方法一:
ok,首先比较容易想到的方法是从上面的原生的查询语句中得到的。其实上面的写法我们可以换个如下:
db.getCollection('test').aggregate([{"$unwind":"$userInfo"},
{"$match":{"userInfo.userTag":"stu","tag":"test"}},
{"$project":{"userInfo":1}}])
这种写法的查询和上面的写法得到的结果是一样的,那么在spring-mongodb中是否有相似的写法呢?
mongoTemplate.getCollection(collectionName).aggregate(List<DBObject> pipeline);
这很棒。下面我们需要做的就是构造一个List<DBObject>
参数:
List<DBObject> dbObjects = new ArrayList<>();
DBObject condition = new BasicDBObject();
DBObject match = new BasicDBObject();
DBObject project = new BasicDBObject();
DBObject unwind = new BasicDBObject();
condition.put("tag", "test");
condition.put("userInfo.userTag", "stu");
match.put("$match", condition);
unwind.put("$unwind", "$userInfo");
project.put("$project", new BasicDBObject("userInfo", 1));
dbObjects.add(unwind);
dbObjects.add(match);
dbObjects.add(project);
所以最终查询方法如下:
mongoTemplate.getCollection("test").aggregate(dbObjects);
ok? 感觉好像少了点什么,结果呢?查询的结果在哪儿? 通过源码我们可以看到:
public AggregationOutput aggregate(List<DBObject> pipeline) {
return this.aggregate(pipeline, this.getReadPreference());
}
这是返回一个AggregationOutput类,下面我们要做的就是从这个类中获取结果(不多说 给代码):
AggregationOutput output = mongoTemplate.getCollection("test").aggregate(dbObjects);
for (Iterator<DBObject> it = output.results().iterator(); it.hasNext(); ) {
BasicDBObject dbo = (BasicDBObject) it.next();
BasicDBObject dbo2 = (BasicDBObject) dbo.get("userInfo");
String name= dbo2.get("name").toString();
String address= dbo2.get("address").toString();
}
附上完整代码;
List<DBObject> dbObjects = new ArrayList<>();
DBObject condition = new BasicDBObject();
DBObject match = new BasicDBObject();
DBObject project = new BasicDBObject();
DBObject unwind = new BasicDBObject();
condition.put("tag", "test");
condition.put("userInfo.userTag", "stu");
match.put("$match", condition);
unwind.put("$unwind", "$userInfo");
project.put("$project", new BasicDBObject("userInfo", 1));
dbObjects.add(unwind);
dbObjects.add(match);
dbObjects.add(project);
AggregationOutput output = mongoTemplate.getCollection("test").aggregate(dbObjects);
for (Iterator<DBObject> it = output.results().iterator(); it.hasNext(); ) {
BasicDBObject dbo = (BasicDBObject) it.next();
BasicDBObject dbo2 = (BasicDBObject) dbo.get("userInfo");
String name= dbo2.get("name").toString();
System.out.println(name);
String address= dbo2.get("address").toString();
System.out.println(address);
}
方法二:
既然spring-mongdb提供mongoTemplate
这个类使用,那么我相信应该会有更加简便的方法使用,那么有没有呢?遇到这种问题,我们应该去官网查看
https://docs.spring.io/spring-data/mongodb/docs/2.0.5.RELEASE/reference/html/#mongo.aggregation
直接上代码:
Aggregation agg = newAggregation(
unwind("$userInfo"),
match(Criteria.where("tag").is("test").and("caseId").is(caseId).and("projectId").is(prjId).and("apmInfo.APMEnum").is(type)),
project("apmInfo")
);
AggregationResults<Object> results = mongoTemplate.aggregate(agg, "APMInfo", Object.class);
List<Object> resultList = results.getMappedResults();
很明显这种方法比第一种方法的代码量要少很多,推荐使用。
总结:
遇到问题时,我们先应该自己思考一下有没有什么合适的解决方案,然后再去官网寻找帮助,有文档看文档,尽量不要先去百度问题。
上述的第一种方法 虽然代码写的有点多,但其实跟原生的语句相差不大,理解比较容易,而且这种原生的方法不止针对aggregate函数,对于任何的原生的语句都可以实现。