Агрегация MongoDB с драйвером Java
Мне нужна ваша помощь для использования MongoDB aggregation framework с драйвером 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"}}
)
элементы в этой коллекции имеют одно или несколько представлений. Мой вопрос не о результате запроса, я хочу знать синтаксис java.
4 ответов
наконец нашел решение, я получаю тот же результат, что и с исходным запросом.
Водитель 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);
}
вы можете сделать его более читаемым со статическим импортом:import static com.mongodb.client.model.Aggregates.*;
.
См.koulini ответ для примера complet.
Водитель 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);
}
логика преобразования запросов : Спасибо этой ссылке
используя предыдущий пример в качестве руководства, вот как это сделать с помощью 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))
));
for (Document doc : output) {
...
}
стоит отметить, что вы можете значительно улучшить код, показанный ответами здесь, используя методы агрегации Java для MongoDB.
давайте возьмем в качестве примера кода ответ 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"))
));
очевидно, что вам понадобится соответствующий статический импорт, но помимо этого, во втором примере кода пылесос, безопасное (как вы не нужно вводить операторы самостоятельно каждый раз), больше читабельный и красивая ИМО.
вот простой способ подсчета сотрудников по departmentId.. Подробности по адресу:агрегация с использованием 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"));
}
});