web-dev-qa-db-ja.com

Javaドライバーを使用したMongoDB集約

MongoDB集計フレームワークをJavaドライバーで使用するためにあなたの助けが必要です。 このドキュメント でも、リクエストの書き方がわかりません。

コレクション内のすべてのアイテムから最も古い200個のビューを取得したい。ここに私のmongoクエリがあります(コンソールモードで欲しいように動作します):

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

このコレクションのアイテムには、1つ以上のビューがあります。私の質問はリクエストの結果に関するものではありません。Java構文を知りたいです。

17
Opsse

最終的に解決策が見つかりましたが、元のリクエストと同じ結果が得られました。

Mongo Driver 3:

ドキュメントの統合

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

Static importで読みやすくすることができます:
import static com.mongodb.client.model.Aggregates.*;
完了例のkouliniの回答 を参照してください。

Mongo Driver 2:

ドキュメントの統合

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 ありがとう このリンク

38
Opsse

MongoDBのJava Aggregationメソッドを使用して、ここでの回答で示されているコードを大幅に改善できることを指摘しておく価値があります。

コード例として、OP自身の質問に対するOPの答えを見てみましょう。

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

上記のコードを次のように書き換えることができます。

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

明らかに、対応する静的インポートが必要になりますが、それを超えて、2番目の例のコードはcleanersafer(演算子を自分で入力する必要がないので時間)、もっと読みやすいそしてもっと美しい IMO。

6
Nikiforos

前の例を参考にして、mongoドライバー3以降を使用して行う方法を次に示します。

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