MongoDB aggregation with Java driver

后端 未结 4 1205
北恋
北恋 2020-11-29 04:34

I need your help for using MongoDB aggregation framework with java driver. I don\'t understand how to write my request, even with this documentation.

I want to get t

相关标签:
4条回答
  • 2020-11-29 05:16

    It is worth pointing out, that you can greatly improve the code shown by the answers here, by using the Java Aggregation methods for MongoDB.

    Let's take as a code example, the OP's answer to his own question.

    AggregateIterable<Document> output = collection.aggregate(Arrays.asList(
            new Document("$unwind", "$views"),
            new Document("$match", new Document("views.isActive", true)),
            new Document("$sort", new Document("views.date", 1)),
            new Document("$limit", 200),
            new Document("$project", new Document("_id", 0)
                        .append("url", "$views.url")
                        .append("date", "$views.date"))
    ));
    

    We can rewrite the above code as follows;

    import static com.mongodb.client.model.Aggregates.*;
    
    AggregateIterable output = collection.aggregate(Arrays.asList(
                    unwind("$views"),
                    match(new Document("views.isActive",true)),
                    sort(new Document("views.date",1)),
                    limit(200),
                    project(new Document("_id",0)
                            .append("url","$views.url")
                            .append("date","$views.date"))
    ));
    

    Obviously, you will need the corresponding static import but beyond that, the code in the second example is cleaner, safer (as you don't have to type the operators yourself every time), more readable and more beautiful IMO.

    0 讨论(0)
  • 2020-11-29 05:29

    Finally found the solution, I get the same result than with the original request.

    Mongo Driver 3 :

    Aggregate doc

    MongoCollection<Document> collection = database.getCollection("myCollection");
    
    AggregateIterable<Document> output = collection.aggregate(Arrays.asList(
            new Document("$unwind", "$views"),
            new Document("$match", new Document("views.isActive", true)),
            new Document("$sort", new Document("views.date", 1)),
            new Document("$limit", 200),
            new Document("$project", new Document("_id", 0)
                        .append("url", "$views.url")
                        .append("date", "$views.date"))
            ));
    
    // Print for demo
    for (Document dbObject : output)
    {
        System.out.println(dbObject);
    }
    

    You can make it more readable with static import :
    import static com.mongodb.client.model.Aggregates.*;.
    See koulini answer for complet example.

    Mongo Driver 2 :

    Aggregate doc

    Iterable<DBObject> output = collection.aggregate(Arrays.asList(
            (DBObject) new BasicDBObject("$unwind", "$views"),
            (DBObject) new BasicDBObject("$match", new BasicDBObject("views.isActive", true)),
            (DBObject) new BasicDBObject("$sort", new BasicDBObject("views.date", 1)),
            (DBObject) new BasicDBObject("$limit", 200),
            (DBObject) new BasicDBObject("$project", new BasicDBObject("_id", 0)
                        .append("url", "$views.url")
                        .append("date", "$views.date"))
            )).results();
        
    // Print for demo
    for (DBObject dbObject : output)
    {
        System.out.println(dbObject);
    }
    

    Query conversion logic : Thank to this link

    0 讨论(0)
  • 2020-11-29 05:31

    Here is a simple way to count employee by departmentId.. Details at: Aggregation using Java API

            Map<Long, Integer> empCountMap = new HashMap<>();
    
            AggregateIterable<Document> iterable = getMongoCollection().aggregate(Arrays.asList(
                    new Document("$match",
                            new Document("active", Boolean.TRUE)
                                    .append("region", "India")),
                    new Document("$group",
                            new Document("_id", "$" + "deptId").append("count", new Document("$sum", 1)))));
    
            iterable.forEach(new Block<Document>() {
                @Override
                public void apply(final Document document) {
                    empCountMap.put((Long) document.get("_id"), (Integer) document.get("count"));
                }
            });
    
    0 讨论(0)
  • 2020-11-29 05:34

    Using previous example as a guide, here's how to do it using mongo driver 3 and up:

    MongoCollection<Document> collection = database.getCollection("myCollection");
    AggregateIterable<Document> output = collection.aggregate(Arrays.asList(
        new Document("$unwind", "$views"),
        new Document("$match", new Document("views.isActive", true))
    ));
    
    for (Document doc : output) {
        ...
    }
    
    0 讨论(0)
提交回复
热议问题