2

I have a collection processedClickLog in MongoDB.

{
        "_id" : ObjectId("58ffb4cefbe21fa7896e2d73"),
        "ID" : "81a5d7f48e5df09c9bc006e7cc89d6e6",
        "USERID" : "206337611536",
        "DATETIME" : "Fri Mar 31 17:29:34 -0400 2017",
        "QUERYTEXT" : "Tom",
        "DOCID" : "www.demo.com",
        "TITLE" : "Harry Potter",
        "TAB" : "People-Tab",
        "TOTALRESULTS" : "1",
        "DOCRANK" : 1
}
{      "id":
        ....
}

I am trying to execute a complex query in java. My query is to get processedClickLog collection where

  1. TAB is not equal to People-Tab
  2. DOCRANK is not equal to 0
  3. only return "USERID", "DOCID", "DOCRANK", "QUERYTEXT" fields
  4. Group by USERID

Below is my Java code. I am able to satisfy the first three condition. But I am stuck on 4th condition which is group by USERID.

String jsonResult = "";
        MongoClient mongoClient = new MongoClient("localhost", 27017);
        MongoDatabase database = mongoClient.getDatabase("test1");
        MongoCollection<Document> collection = database.getCollection("processedClickLog");
        //add condition where TAB is not equal to "People-Tab" and DOCRANK is not equal to 0
        List<DBObject> criteria = new ArrayList<DBObject>();
        criteria.add(new BasicDBObject("DOCRANK", new BasicDBObject("$ne", 0)));
        criteria.add(new BasicDBObject("TAB", new BasicDBObject("$ne", "People-Tab")));

            //combine the above two conditions
            BasicDBObject query = new BasicDBObject("$and", criteria);
            //to retrieve all the documents with specific fields 
            MongoCursor<Document> cursor = collection.find(query)
                    .projection(Projections.include("USERID", "DOCID", "DOCRANK", "QUERYTEXT")).iterator();
      try {
                while (cursor.hasNext()) {
                    System.out.println(cursor.next().toJson());

                }
            } finally {
                cursor.close();
            }
            System.out.println(hashMap);
            mongoClient.close();
    }

How should I define my whole query to add the condition "group by USERID" in java? Any help is appreciated

1 Answer 1

6

You've to use aggregation framework. Statically import all the methods of helper classes and use the below code.

Use of BasicDBObject is not required in newer 3.x driver api. You should use the new class Document for similar needs.

import static com.mongodb.client.model.Accumulators.*;
import static com.mongodb.client.model.Aggregates.*;
import static java.util.Arrays.asList;
import static com.mongodb.client.model.Filters.*;
import static com.mongodb.client.model.Projections.*;

Bson match = match(and(ne("DOCRANK", 0), ne("TAB", "People-Tab")));
Bson group = group("$USERID", first("USERID", "$USERID"), first("DOCID", "$DOCID"), first("DOCRANK", "$DOCRANK"), first("QUERYTEXT", "$QUERYTEXT"));
Bson projection = project(fields(include("USERID", "DOCID", "DOCRANK", "QUERYTEXT"), excludeId()));
MongoCursor<Document> cursor = collection.aggregate(asList(match, group, projection)).iterator();

Projection stage is optional, only added to give a complete example.

More about aggregation here https://docs.mongodb.com/manual/reference/operator/aggregation/

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

4 Comments

Thanks. I will try this and let you know
Worked like a charm. Thanks a lot
Can you explain in brief about the group part? I didn't find anything related to that in the reference link.
You are welcome. Its same as group concept in sql. You group by a key and run accumulators to collect the data. For more on how to use group with java driver go here mongodb.github.io/mongo-java-driver/3.1/builders/aggregation/…

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.