MongoDB 聚合与 Java 驱动程序
MongoDB aggregation with Java driver
我需要你的帮助才能将 MongoDB 聚合框架与 java 驱动程序一起使用。
我不明白如何写我的请求,即使 this documentation.
我想从我的 collection 中的所有项目中获取最旧的 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"}}
)
此 collection 中的项目有一个或多个视图。
我的问题不是关于请求结果,我想知道 java 句法。
终于找到了解决方案,我得到的结果与原始请求相同。
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);
}
您可以使用静态导入使其更具可读性:
import static com.mongodb.client.model.Aggregates.*;
.
参见 koulini answer for complet example。
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);
}
查询转换逻辑:
感谢 this link
使用前面的示例作为指南,下面是如何使用 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) {
...
}
这里有一个简单的方法来按 departmentId 计算员工数..
详情见: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"));
}
});
值得指出的是,通过使用 MongoDB 的 Java 聚合方法,您可以大大改进此处答案显示的代码。
让我们以代码示例为例,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"))
));
显然,您将需要相应的静态导入,但除此之外,第二个示例中的代码是 cleaner、safer(如您不必每次都自己输入运算符),更多可读和更多美丽 IMO。
我需要你的帮助才能将 MongoDB 聚合框架与 java 驱动程序一起使用。 我不明白如何写我的请求,即使 this documentation.
我想从我的 collection 中的所有项目中获取最旧的 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"}}
)
此 collection 中的项目有一个或多个视图。 我的问题不是关于请求结果,我想知道 java 句法。
终于找到了解决方案,我得到的结果与原始请求相同。
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);
}
您可以使用静态导入使其更具可读性:
import static com.mongodb.client.model.Aggregates.*;
.
参见 koulini answer for complet example。
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);
}
查询转换逻辑:
使用前面的示例作为指南,下面是如何使用 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) {
...
}
这里有一个简单的方法来按 departmentId 计算员工数.. 详情见: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"));
}
});
值得指出的是,通过使用 MongoDB 的 Java 聚合方法,您可以大大改进此处答案显示的代码。
让我们以代码示例为例,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"))
));
显然,您将需要相应的静态导入,但除此之外,第二个示例中的代码是 cleaner、safer(如您不必每次都自己输入运算符),更多可读和更多美丽 IMO。