使用 Java 驱动程序进行 MongoDB 聚合
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/31643109/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
MongoDB aggregation with Java driver
提问by Opsse
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.
我需要你的帮助来使用带有 Java 驱动程序的 MongoDB 聚合框架。我不明白如何写我的请求,即使有这个文档。
I want to get the 200 oldest views from all items in my collection. Here is my mongo query (which works like I want in console mode):
我想从我的收藏中的所有项目中获取 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"}}
)
Items in this collection have one or many views. My question is not about the request result, I want to know the java syntaxe.
此集合中的项目具有一个或多个视图。我的问题不是关于请求结果,我想知道java语法。
采纳答案by Opsse
Finally found the solution, I get the same result than with the original request.
终于找到了解决方案,我得到了与原始请求相同的结果。
Mongo Driver 3 :
蒙戈司机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);
}
You can make it more readable with static import :import static com.mongodb.client.model.Aggregates.*;
.
See koulini answer for complet example.
您可以使用静态导入使其更具可读性:import static com.mongodb.client.model.Aggregates.*;
。
有关完整示例,请参阅koulini 答案。
Mongo Driver 2 :
蒙戈司机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 :Thank to this link
查询转换逻辑:感谢此链接
回答by Andres
Using previous example as a guide, here's how to do it using mongo driver 3 and up:
使用前面的示例作为指南,以下是使用 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) {
...
}
回答by Ashutosh Srivastav
Here is a simple way to count employee by departmentId.. Details at: Aggregation using Java API
这是按部门 ID 计算员工的简单方法。详情见:使用 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"));
}
});
回答by Nikiforos
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.
值得指出的是,通过使用 MongoDB 的 Java 聚合方法,您可以大大改进此处答案所示的代码。
Let's take as a code example, the OP's answer to his own question.
让我们以代码示例为例,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"))
));
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 readableand more beautifulIMO.
显然,您将需要相应的静态导入,但除此之外,第二个示例中的代码更简洁、更安全(因为您不必每次都自己键入操作符)、更易读、更美观的IMO。