How to write multiple group by id fields in Mongod

2019-05-06 21:27发布

问题:

In the below query

{ $group : {
        _id :  { success:'$success', responseCode:'$responseCode', label:'$label'},
        max_timeStamp : { $timeStamp : 1 },
        count_responseCode : { $sum : 1 },
        avg_value : { $sum : "$value" },
        count_success : { $sum : 1 }
    }}

How _id : { success:'$success', responseCode:'$responseCode', label:'$label'}, can be translated to use in java mongodb driver.

I tried

BasicDBList list = new BasicDBList();
list.add(new BasicDBObject("success", "$success"));
list.add(new BasicDBObject("responseCode", "$responseCode"));
list.add(new BasicDBObject("label", "$label"));
AggregationOutput output = collection.aggregate(match, project, group); 

and

Multi-dimension array

String [][] muitiGroupBy = {{"success", "$success"},{"responseCode", "$responseCode"},{"label", "$label"}};

etc..

But i always get like this as result

"_id" : [ { "success" : "$success"} , { "responseCode" : "$responseCode"}]

If I use only one field it works.

DBObject groupFields = new BasicDBObject( "_id", new BasicDBObject("success", "$success"));

回答1:

We did figure out how. We can achieve by using this.

Map<String, Object> dbObjIdMap = new HashMap<String, Object>();
dbObjIdMap.put("success", "$success");
dbObjIdMap.put("responseCode", "$responseCode");
dbObjIdMap.put("label", "$label");
DBObject groupFields = new BasicDBObject( "_id", new BasicDBObject(dbObjIdMap));


回答2:

I could achieve this through this code (grails code and mongo-java-driver-3.2):

DBObject groupFields = new BasicDBObject()
groupFields.put('success', "\$success")
groupFields.put('responseCode', "\$responseCode")
groupFields.put('label', "\$label")
def result = collection.aggregate(Arrays.asList(Aggregates.group(groupFields, []))).iterator()


回答3:

I had a similar need and titogeo's answer from 2013 led me in the right direction after many failed attempts to translate my aggregation operation into something the Java client could handle. This is what I used:

MongoCollection<Document> myCollection = myDB.getCollection("myCollection");

Map<String, Object> multiIdMap = new HashMap<String, Object>();
multiIdMap.put("groupField1", "$groupField1");
multiIdMap.put("groupField2", "$groupField2");

Document groupFields = new Document(multiIdMap);
AggregateIterable<Document> aggregate = myCollection.aggregate(Arrays.asList(
        Aggregates.group(groupFields,
                Accumulators.last("lastDate", "$dateCreated"),
                Accumulators.last("lastNumAvail", "$availableUnits")
                )
        ));

I got back exactly what I needed to match the result from this:

db.myCollection.aggregate([
            {"$group":{ "_id":{
                groupField1: "$groupField1", 
                groupField2: "$groupField2"}, 
                lastDate: 
                    {"$last":"$dateCreated"}, 
                lastNumAvail: 
                    {"$last":"$availableUnits"}
                }
               }                
            ]);