1. BasicDBObject
The entire aggregation query is to count the number of users in various states of users as scenarios:
1. Filter criteria:
date is the query date:
BasicDBObject Query = new BasicDBObject(); Query.put("time",new BasicDBObject("$gte", date + " 00:00:00") .append("$lte", date + " 23:59:59"));If there are multiple conditions: add Query.put("status", 0);
If there is OR filter:
BasicDBList values = new BasicDBList(); values.add(new BasicDBObject("status", new BasicDBObject("$exists",false))); values.add(new BasicDBObject("status", 0));Query.put("$or", values);where new BasicDBObject("$exists", false)) means that "status" does not exist (mongodb document can not be equal to an entity field)
2. Splicing match
DBObject Match = new BasicDBObject("$match", Query);Put the previous Query into the macth filter
3. Splicing and grouping conditions
This step is equivalent to SQL Group By
BasicDBObject GroupBy = new BasicDBObject();// Grouping conditions GroupBy.put("userId", "$userId");// Group according to user IDLike the filtering step in the first step, if there are multiple groups, you can directly add them to the following: GroupBy.put("status", "$status");
4. Post-group query
First splice the groupings:
DBObject Select = new BasicDBObject("_id", GroupBy);If we want to operate on the grouped data: (Here is the statistics of users)
Select.put("count", new BasicDBObject("$sum", 1));5. Splice $group
DBObject Group = new BasicDBObject("$group", Select);So far. Let's splice the mongodb statement end here
Let's start the query operation:
import com.mongodb.AggregationOutput;import org.springframework.data.mongodb.core.MongoTemplate;AggregationOutput Output = mongoTemplate.getCollection("Here is the data table name of mongodb") .aggregate(Match, Group);Read the query result:
Iterable<DBObject> map = Output.results();//Transip mapfor (DBObject dbObject : map) { //The map read here is {"_id":{"userId":1,"status"0}}... Map<String, Object> resultMap = (Map<String, Object>) dbObject.get("_id"); //Transfer.0 Integer userId = Integer.parseInt(CommUtil.toString(ausgMap.get("userId")).replace(".0","")); //Here we can operate on our data; Integer count = Integer.parseInt(CommUtil.toString(dbObject.get("count"))); }2. DBObject
Without further ado, if you think the first method is particularly long-term, then I will bring you a more concise aggregation query with a more concise code:
Just upload the code.
1. Pay attention to the imported package:
import com.mongodb.DBObject; import com.mongodb.util.JSON;
2.$macth:
(beginDay-Query start date; endDay-Query end date)
DBObject match = (DBObject) JSON.parse("{$match:{'status':'1','time': {$gte:'"+beginDay+"',$lte:'"+endDay+"'}}}");3.$group:
(Grouped by userId, count the number of users, accumulate the amout field value, and take the maximum value of the amout field)
DBObject group = (DBObject) JSON.parse("{$group:{_id:'$userId', count:{$sum:1},total:{$sum:'$amount'},maxSigle:{$max:'$amount'}}}");After the conditions are spliced, start querying:
List<DBObject> list = new ArrayList<DBObject>();list.add(match); list.add(group);AggregationOutput Output = mongoTemplate.getCollection("table name").aggregate(list);There is no need to talk about the traversal result. The above has been described in detail
Is the second method much simpler than the other? But it tests one's familiarity with mongodb statements.
【Extended】
Then the above method expands
//status is 0 or 1; type not 11; time DBObject match = (DBObject) JSON.parse("{$match:{'status':{$in:['0','1']}, type:{$ne:11},'time':{$gte:'+beginDay+"',$lte:'+endDay+"'}}}");//Group by user ID, count the number of queries, and take the time of the last time DBObject group = (DBObject) JSON.parse("{$group:{_id:'$userId', count:{$sum:1},lastTime:{$max:'$time'} }}");//In the results counted in the previous step, data with filtering times greater than 100 times DBObject groupMatch = (DBObject) JSON.parse("{$match:{count:{$gte:100}}}");//$project----What fields should be displayed in the query result, and the display is set to 1. The _id field (field) needs not be displayed as follows, so you need to specify it as follows: //db. Collection name.aggregate( [ { $project : { _id: 0, count: 1 , lastSuccTime: 1 } } ] )DBObject project = (DBObject) JSON.parse("{$project:{_id:1,count:1,lastSuccTime:1}}");DBObject sort = (DBObject) JSON.parse("{$sort:{'count':-1}}");//Sorting List<DBObject> list = new ArrayList<DBObject>();list.add(match);list.add(group);list.add(groupMatch);list.add(project);list.add(sort);AggregationOutput catchOutPut = mongoTemplate.getCollection("table name") .aggregate(list);//Query results3. BasicDBObject+Script Statement
BasicDBObject groupIndex = new BasicDBObject();BasicDBObject distinctQuery = new BasicDBObject();distinctQuery.put("userId", new BasicDBObject("$in", userIds));//UserIds array BasicDBObject initIndex = new BasicDBObject();initIndex.put("count", 0);//Assign initial value to count// Script (doc represents the data of the database.prev represents the query result//prev.count The count here is the count of the previous step initIndex) String reduce = "function(doc, prev) {if(doc.status==0){prev.count+= 1;};}";List<Map<String, Object>> basicDBList = (List<Map<String, Object>>) mongoTemplate. getCollection("Collection").group(groupIndex, distinctQuery, initIndex, reduce, null);Finally, you can get the result by looping through List. [PS: There is a restriction on this aggregation method of group--->There will be an error if it exceeds 20,000 data]
The above is what I use mongodb aggregation processing in ordinary business processing. If there is a better method or something that needs improvement, please leave me a message~