Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to write multiple group by id fields in Mongodb java driver

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"));

like image 613
titogeo Avatar asked Mar 22 '13 06:03

titogeo


2 Answers

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));
like image 98
titogeo Avatar answered Sep 20 '22 13:09

titogeo


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"}
                }
               }                
            ]);
like image 29
zerpsed Avatar answered Sep 23 '22 13:09

zerpsed