web-dev-qa-db-fra.com

Agrégation MongoDB avec Java

J'ai besoin de votre aide pour utiliser le framework d'agrégation MongoDB avec Java. Je ne comprends pas comment écrire ma demande, même avec cette documentation .

Je veux obtenir les 200 vues les plus anciennes de tous les articles de ma collection. Voici ma requête mongo (qui fonctionne comme je veux en mode console):

db.myCollection.aggregate(
    {$unwind : "$views"},
    {$match : {"views.isActive" : true}},
    {$sort : {"views.date" : 1}},
    {$limit : 200},
    {$project : {"_id" : 0, "url" : "$views.url", "date" : "$views.date"}}
)

Les éléments de cette collection ont une ou plusieurs vues. Ma question ne concerne pas le résultat de la requête, je veux connaître la syntaxe Java.

17
Opsse

Enfin trouvé la solution, j'obtiens le même résultat qu'avec la demande d'origine.

Mongo Driver 3:

doc agrégé

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

Vous pouvez le rendre plus lisible avec l'importation statique:
import static com.mongodb.client.model.Aggregates.*;.
Voir réponse koulini pour un exemple complet .

Mongo Driver 2:

doc agrégé

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

Logique de conversion des requêtes: Query conversion logic Merci à ce lien

38
Opsse

Il convient de souligner que vous pouvez améliorer considérablement le code affiché par les réponses ici, en utilisant les méthodes d'agrégation Java pour MongoDB.

Prenons comme exemple de code, la réponse du PO à sa propre 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"))
));

Nous pouvons réécrire le code ci-dessus comme suit;

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

De toute évidence, vous aurez besoin de l'importation statique correspondante, mais au-delà, le code dans le deuxième exemple est plus propre, plus sûr (car vous n'avez pas à taper les opérateurs vous-même tous les temps), plus lisible et plus bea IMO.

6
Nikiforos

En utilisant l'exemple précédent comme guide, voici comment le faire en utilisant le pilote mongo 3 et plus:

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) {
    ...
}
3
Andres