Java 聚合框架-组操作抛出NumberFormatException
我正在使用Java 聚合框架-组操作抛出NumberFormatException,java,mongodb,spring-data-mongodb,Java,Mongodb,Spring Data Mongodb,我正在使用Spring数据MongoDB聚合框架 下面是一个代码示例: Aggregation agg = Aggregation.newAggregation( match(Criteria.where("type").is("PROMO")), group("locale")//.count().as("counts") ); AggregationResults<Message> results = mongoTemplate.aggregate(agg,
Spring数据MongoDB聚合框架
下面是一个代码示例:
Aggregation agg = Aggregation.newAggregation(
match(Criteria.where("type").is("PROMO")),
group("locale")//.count().as("counts")
);
AggregationResults<Message> results = mongoTemplate.aggregate(agg, "message", Message.class);
return results.getMappedResults();
CL
是locale字段上的一个值,但我不明白为什么要抛出该异常。
我使用了一个类似的例子
已解决:
Aggregation agg = Aggregation.newAggregation(
match(Criteria.where("type").is("PROMO")),
group("created", "text").addToSet("locale").as("countries").addToSet("device.deviceType").as("platforms").count().as("count")
);
我在mongo控制台上尝试了一个简单的示例。之后,将操作映射到生成器。
我不明白为什么以前不工作。如果有人能解决这个问题,那就太好了
模型“消息”:
我的简单答案是避免直接使用MongoDB Spring数据类进行聚合,并使用标准的MongoDB Java对象,例如
DBObject/AggregationOutput
。原因是我花了几个小时试图在MongoDB Spring数据中获得除基本聚合查询之外的任何查询(这是使用最新的,到今天为止是Spring数据MongoDB 1.5.0.RELEASE)
但是,使用标准MongoDB Java对象构建聚合查询可能是一件痛苦的事情(特别是在嵌套/复杂的情况下),因为您最终会创建无数DBObject groupFields=new BasicDBObject(“_id”,null)代码>和代码看起来一团糟
我建议在代码中添加以下3种包装方法
protected DBObject dbObj (String key, Object value) {
return new BasicDBObject (key, value);
}
protected DBObject dbObj (Object ... objs) {
DBObject dbObj = new BasicDBObject();
if (objs.length % 2 == 0) {
for (int i = 0; i < objs.length; i+=2) {
dbObj.put((String)objs[i], objs[i+1]);
}
}
return dbObj;
}
protected DBObject dbList (Object ... objs) {
BasicDBList dbList = new BasicDBList();
for (Object obj : objs) {
dbList.add(obj);
}
return (DBObject)dbList;
}
。。。那么您的Java代码将如下所示
List<DBObject> aggregation = Arrays.asList (
dbObj ("$group", dbObj (
"_id", dbObj ("state", "$state", "city", "$city"),
"pop", dbObj ("$sum", "$post")
)),
dbObj ("$sort", dbObj ("pop", 1)),
dbObj ("$group", dbObj (
"_id", "$_id.state",
"biggestCity", dbObj ("$last", "$_id.city"),
"biggestPop", dbObj ("$last", "$pop"),
"smallestCity", dbObj ("$first", "$_id.city"),
"smallestPop", dbObj ("$first", "$pop")
)),
dbObj ("$project", dbObj (
"_id", 0,
"state", "$_id",
"biggestCity", dbObj ("name", "$biggestCity", "pop", "$biggestPop"),
"smallestCity", dbObj ("name", "$smallestCity", "pop", "$smallestPop")
))
);
// Run aggregation query
DBCollection collection = mongoTemplate.getCollection(COLLECTION_NAME);
AggregationOutput output = collection.aggregate (aggregation);
List aggregation=Arrays.asList(
dbObj(“$group”,dbObj(
“_id”,dbObj(“州”,“州”,“市”,“市”),
“pop”,dbObj(“$sum”,“$post”)
)),
dbObj(“$sort”,dbObj(“pop”,1)),
dbObj(“$group”,dbObj(
“\u id”、“$\u id.state”,
“biggestCity”,dbObj($last“,$u id.city”),
“biggestPop”,dbObj(“$last”,“$pop”),
“smallestCity”,dbObj(“$first”,“$id.city”),
“smallestPop”,dbObj(“$first”,“$pop”)
)),
dbObj(“$project”,dbObj(
“_id”,0,
“state”、“$\u id”,
“biggestCity”,dbObj(“名称”,“$biggestCity”,“pop”,“$biggestPop”),
“smallestCity”,dbObj(“名称”,“$smallestCity”,“流行音乐”,“$smallestPop”)
))
);
//运行聚合查询
DBCollection collection=mongoTemplate.getCollection(集合名称);
AggregationOutput输出=collection.aggregate(聚合);
这样做,如果它在你的编辑器(例如RoboMongo)中工作,它将在你的Java代码中工作,尽管你将不得不从结果中手动转换对象,这不会太痛苦,例如
List<MyResultClass> results = new ArrayList<MyResultClass>();
Iterator<DBObject> it = output.results().iterator();
while (it.hasNext()) {
DBObject obj = it.next();
MyResultClass result = mongoTemplate.getConverter().read(MyResultClass.class, obj);
results.add(result);
}
List results=new ArrayList();
迭代器it=output.results().Iterator();
while(it.hasNext()){
DBObject obj=it.next();
MyResultClass result=mongoTemplate.getConverter().read(MyResultClass.class,obj);
结果。添加(结果);
}
但是,您可能会发现Spring数据聚合的东西确实适合您。我喜欢Spring,我确实在代码的各个部分使用了Mongo Spring数据,这是聚合支持让它失望了,例如,在一个包含多个项目的“$group”中执行“$push”似乎不起作用。我相信它会随着时间(和更好的文档)而改进。其他人也赞同这些想法,例如-参见第4节
快乐编码 我的简单答案是避免直接使用MongoDB Spring数据类进行聚合,并使用标准的MongoDB Java对象,例如DBObject/AggregationOutput
。原因是我花了几个小时试图在MongoDB Spring数据中获得除基本聚合查询之外的任何查询(这是使用最新的,到今天为止是Spring数据MongoDB 1.5.0.RELEASE)
但是,使用标准MongoDB Java对象构建聚合查询可能是一件痛苦的事情(特别是在嵌套/复杂的情况下),因为您最终会创建无数DBObject groupFields=new BasicDBObject(“_id”,null)代码>和代码看起来一团糟
我建议在代码中添加以下3种包装方法
protected DBObject dbObj (String key, Object value) {
return new BasicDBObject (key, value);
}
protected DBObject dbObj (Object ... objs) {
DBObject dbObj = new BasicDBObject();
if (objs.length % 2 == 0) {
for (int i = 0; i < objs.length; i+=2) {
dbObj.put((String)objs[i], objs[i+1]);
}
}
return dbObj;
}
protected DBObject dbList (Object ... objs) {
BasicDBList dbList = new BasicDBList();
for (Object obj : objs) {
dbList.add(obj);
}
return (DBObject)dbList;
}
。。。那么您的Java代码将如下所示
List<DBObject> aggregation = Arrays.asList (
dbObj ("$group", dbObj (
"_id", dbObj ("state", "$state", "city", "$city"),
"pop", dbObj ("$sum", "$post")
)),
dbObj ("$sort", dbObj ("pop", 1)),
dbObj ("$group", dbObj (
"_id", "$_id.state",
"biggestCity", dbObj ("$last", "$_id.city"),
"biggestPop", dbObj ("$last", "$pop"),
"smallestCity", dbObj ("$first", "$_id.city"),
"smallestPop", dbObj ("$first", "$pop")
)),
dbObj ("$project", dbObj (
"_id", 0,
"state", "$_id",
"biggestCity", dbObj ("name", "$biggestCity", "pop", "$biggestPop"),
"smallestCity", dbObj ("name", "$smallestCity", "pop", "$smallestPop")
))
);
// Run aggregation query
DBCollection collection = mongoTemplate.getCollection(COLLECTION_NAME);
AggregationOutput output = collection.aggregate (aggregation);
List aggregation=Arrays.asList(
dbObj(“$group”,dbObj(
“_id”,dbObj(“州”,“州”,“市”,“市”),
“pop”,dbObj(“$sum”,“$post”)
)),
dbObj(“$sort”,dbObj(“pop”,1)),
dbObj(“$group”,dbObj(
“\u id”、“$\u id.state”,
“biggestCity”,dbObj($last“,$u id.city”),
“biggestPop”,dbObj(“$last”,“$pop”),
“smallestCity”,dbObj(“$first”,“$id.city”),
“smallestPop”,dbObj(“$first”,“$pop”)
)),
dbObj(“$project”,dbObj(
“_id”,0,
“state”、“$\u id”,
“biggestCity”,dbObj(“名称”,“$biggestCity”,“pop”,“$biggestPop”),
“smallestCity”,dbObj(“名称”,“$smallestCity”,“流行音乐”,“$smallestPop”)
))
);
//运行聚合查询
DBCollection collection=mongoTemplate.getCollection(集合名称);
AggregationOutput输出=collection.aggregate(聚合);
这样做,如果它在你的编辑器(例如RoboMongo)中工作,它将在你的Java代码中工作,尽管你将不得不从结果中手动转换对象,这不会太痛苦,例如
List<MyResultClass> results = new ArrayList<MyResultClass>();
Iterator<DBObject> it = output.results().iterator();
while (it.hasNext()) {
DBObject obj = it.next();
MyResultClass result = mongoTemplate.getConverter().read(MyResultClass.class, obj);
results.add(result);
}
List results=new ArrayList();
迭代器it=output.results().Iterator();
while(it.hasNext()){
DBObject obj=it.next();
MyResultClass result=mongoTemplate.getConverter().read(MyResultClass.class,obj);
结果。添加(结果);
}
但是,您可能会发现Spring数据聚合的东西确实适合您。我喜欢Spring,我确实在代码的各个部分使用了Mongo Spring数据,这是聚合支持让它失望了,例如,在一个包含多个项目的“$group”中执行“$push”似乎不起作用。我相信它会随着时间(和更好的文档)而改进。其他人也赞同这些想法,例如-参见第4节
快乐编码 我的简单答案是避免直接使用MongoDB Spring数据类进行聚合,并使用标准的MongoDB Java对象,例如DBObject/AggregationOutput
。原因是我花了好几个小时试图得到基本agg以外的任何东西