6

I'm trying to perform an aggregation operation using in Java using the mongo-java-driver. I've performed some other find operations, but I'm unable to do the following aggregation correctly in Java:

db.I1.aggregate([
    { "$match": { "ci": 862222} },
    { "$match": { "gi": { "$ne": null } }},
    { "$group": {
        "_id": {
            "ci": "$ci",
            "gi": "$gi",
            "gn": "$gn",
            "si": "$si"
        }
    }},
    { "$group": {
        "_id": {
            "ci": "$_id.ci",
            "gi": "$_id.gi",
            "gn": "$_id.gn"
        },
        "sn": { "$sum": 1 }
    }},
    { "$sort" : { "_id.gi" : 1}}
])

I've tried several ways and methods to perform that aggregation in Java, but I'm unable to include the group fields "ci", "gi", "gn","si" correctly in the coll.aggregate(asList()) method. What I got so far, is the following:

MongoCollection<Document> coll = mongo.getCollection("I1");

Document matchCourse = new Document("$match",
    new Document("ci", Integer.parseInt(courseid)));

Document matchGroupNotNull = new Document("$match",
    new Document("gi", new Document("$ne", null)));

List<Object> list1 = new BasicDBList();
    list1.add(new BasicDBObject("ci", "$ci"));
    list1.add(new BasicDBObject("gi", "$gi"));
    list1.add(new BasicDBObject("gn", "$gn"));
    list1.add(new BasicDBObject("si", "$si"));

Document group1 = new Document(
    "_id", list1).append("count", new Document("$sum", 1));

List<Object> list2 = new BasicDBList();
list2.add(new BasicDBObject("ci", "$_id.ci"));
list2.add(new BasicDBObject("gi", "$_id.gi"));
list2.add(new BasicDBObject("gn", "$_id.gn"));

Document group2 = new Document(
    "_id", list2).append("sn", new Document("$sum", 1));

Document sort = new Document("$sort", 
    new Document("_id.gi", 1));

AggregateIterable<Document> iterable = coll.aggregate(asList(matchCourse,
    matchGroupNotNull, group1, group2, sort));

I know it's not correct, but I included it to give you an idea of what I am doing. I've googled this in many different ways and read several pages, but I didn't find any solution. The available documentation for MongoDB-Java(1, 2) is too short for me and doesn't include this case.

How can I perform that query in Java? Any help would be appreciated.

Thank you very much!!

2 Answers 2

12

Finally I've come to a solution. There were some errors in the question that I posted, as it was the last attempt after reaching some point of desperation, but finally, here is the final solution:

MongoDatabase mongo = // initialize your connection;
Document matches = new Document("$match",
    new Document("gi", new Document("$ne", null))
    .append("ci", Integer.parseInt(courseid)));

Document firstGroup = new Document("$group",
    new Document("_id",
        new Document("ci", "$ci")
        .append("gi", "$gi")
        .append("gn", "$gn")
        .append("si", "$si"))
    .append("count", new Document("$sum", 1)));

Document secondGroup = new Document("$group",
    new Document("_id",
        new Document("ci", "$_id.ci")
        .append("gi", "$_id.gi")
        .append("gn", "$_id.gn"))
    .append("ns", new Document("$sum", 1))); 

Document sort = new Document("$sort", 
    new Document("_id.gi", 1));             

List<Document> pipeline = Arrays.asList(matches, firstGroup,
    secondGroup, sort);
AggregateIterable<Document> cursor = mongo.getCollection("I1")
    .aggregate(pipeline);

for(Document doc : cursor) { // do stuff with doc }

Instead of trying to create lists of key-values, I just appended the elements to the documents. Hope it will be useful for somebody!!

Sign up to request clarification or add additional context in comments.

Comments

0

This question is quite old but was the top match on google when I searched so if anyone is looking for a solution to this I managed to do it in the following way

Aggregation.group(Fields.fields()
            .and("field1")
            .and("field2"))
            .first("name")
            .`as`("name")
            .count().`as`("count")

This will produce the following MDB query:

   { "$group" : 
        { "_id" : 
        { "field1" : "$field1", "field2" : "$field2"}, 
        "name" : { "$first" : "$name"}, 
        "count" : { "$sum" : 1}
   }

1 Comment

This API looks like it's specific to Spring Data

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.