地址:http://blog.csdn.net/bicheng4769/article/details/79626382
{
"_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}}])
mongoTemplate
这个类来进行增删改查。我们这里只是介绍使用aggregate这个函数的使用方法,其他的操作可以参考文档 方法一:
ok,首先比较容易想到的方法是从上面的原生的查询语句中得到的。其实上面的写法我们可以换个如下:
db.getCollection('test').aggregate([{
"$unwind":"$userInfo"},
{
"$match":{
"userInfo.userTag":"stu","tag":"test"}},
{
"$project":{
"userInfo":1}}])
这种写法的查询和上面的写法得到的结果是一样的,那么在spring-mongodb中是否有相似的写法呢?
mongoTemplate.getCollection(collectionName).aggregate(List pipeline);
这很棒。下面我们需要做的就是构造一个List
参数:
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 pipeline) {
return this.aggregate(pipeline, this.getReadPreference());
}
这是返回一个AggregationOutput类,下面我们要做的就是从这个类中获取结果(不多说 给代码):
AggregationOutput output = mongoTemplate.getCollection("test").aggregate(dbObjects);
for (Iterator 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 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 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函数,对于任何的原生的语句都可以实现。