无法序列化 class org.springframework.data.geo.Point
can't serialize class org.springframework.data.geo.Point
我正在尝试使用 spring-data-mongodb 1.6.2 对一些 GPS 数据进行聚合查询。这是它的样子:
Aggregation agg = newAggregation(
match(new Criteria()
.andOperator(
Criteria.where("eventTime").gte(filterDate),
Criteria.where("location").nearSphere(p).maxDistance(distance)
)
),
sort(Direction.DESC, "vanId", "eventTime"),
group("vanId").first(Aggregation.ROOT).as("first")
);
return mongoTemplate.aggregate(agg,GpsDataEntity.MONGO_COLLECTION, GroupedEntity2.class);`
我看到的问题必须归因于查询的 match() 部分。异常真的很长,所以我只包含了堆栈,直到在上面的代码片段中调用 mongoTemplate.aggregate() 的点:
Caused by: java.lang.IllegalArgumentException: can't serialize class
org.springframework.data.geo.Point at
org.bson.BasicBSONEncoder._putObjectField(BasicBSONEncoder.java:284)
at org.bson.BasicBSONEncoder.putObject(BasicBSONEncoder.java:185) at
org.bson.BasicBSONEncoder._putObjectField(BasicBSONEncoder.java:240)
at org.bson.BasicBSONEncoder.putObject(BasicBSONEncoder.java:185) at
org.bson.BasicBSONEncoder._putObjectField(BasicBSONEncoder.java:240)
at org.bson.BasicBSONEncoder.putObject(BasicBSONEncoder.java:199) at
org.bson.BasicBSONEncoder._putObjectField(BasicBSONEncoder.java:240)
at org.bson.BasicBSONEncoder.putObject(BasicBSONEncoder.java:185) at
org.bson.BasicBSONEncoder._putObjectField(BasicBSONEncoder.java:240)
at org.bson.BasicBSONEncoder.putObject(BasicBSONEncoder.java:185) at
org.bson.BasicBSONEncoder._putObjectField(BasicBSONEncoder.java:240)
at org.bson.BasicBSONEncoder.putIterable(BasicBSONEncoder.java:309)
at
org.bson.BasicBSONEncoder._putObjectField(BasicBSONEncoder.java:248)
at org.bson.BasicBSONEncoder.putObject(BasicBSONEncoder.java:185) at
org.bson.BasicBSONEncoder.putObject(BasicBSONEncoder.java:131) at
com.mongodb.DefaultDBEncoder.writeObject(DefaultDBEncoder.java:33) at
com.mongodb.OutMessage.putObject(OutMessage.java:289) at
com.mongodb.OutMessage.writeQuery(OutMessage.java:211) at
com.mongodb.OutMessage.query(OutMessage.java:86) at
com.mongodb.DBCollectionImpl.find(DBCollectionImpl.java:81) at
com.mongodb.DB.command(DB.java:317) at
com.mongodb.DB.command(DB.java:296) at
com.mongodb.DB.command(DB.java:371) at
com.mongodb.DB.command(DB.java:243) at
org.springframework.data.mongodb.core.MongoTemplate.doInDB(MongoTemplate.java:326)
at
org.springframework.data.mongodb.core.MongoTemplate.doInDB(MongoTemplate.java:324)
at
org.springframework.data.mongodb.core.MongoTemplate.execute(MongoTemplate.java:394)
at
org.springframework.data.mongodb.core.MongoTemplate.executeCommand(MongoTemplate.java:324)
at
org.springframework.data.mongodb.core.MongoTemplate.aggregate(MongoTemplate.java:1418)
at
org.springframework.data.mongodb.core.MongoTemplate.aggregate(MongoTemplate.java:1353)
如果我删除 nearSphere 条件,上述查询工作正常。我已经验证传递的点和距离是有效的。
如果有人能指出我做错了什么,我将不胜感激。
这不是 Spring 数据 MongoDB 中的错误。
实际上,$match 聚合表达式中不允许使用“$nearSphere”。
您必须改用 geoNear(..) - 请参阅下面的示例。
请注意 mongodb 要求 geoNear 是聚合管道中的第一个元素。
@Test
public void serializePoinInCriteriaNearSphere() throws Exception {
mongoTemplate.dropCollection(EventWithLocation.class);
mongoTemplate.insert(new EventWithLocation(3, new Point(-73.99408, 40.75057), "42"));
mongoTemplate.indexOps(EventWithLocation.class).ensureIndex(new GeospatialIndex("location"));
Point p = new Point(-73, 40);
NearQuery geoNear = NearQuery.near(p, Metrics.KILOMETERS).maxDistance(150.0);
TypedAggregation<EventWithLocation> agg = newAggregation(EventWithLocation.class, //
geoNear(geoNear, "distance") //
, match(where("eventTime").gte(1)) //
, sort(Direction.DESC, "eventTime") //
, group("vanId").first(Aggregation.ROOT).as("first") //
);
AggregationResults<DBObject> results = mongoTemplate.aggregate(agg, DBObject.class);
List<DBObject> list = results.getMappedResults();
DBObject firstResult = list.get(0);
assertThat(firstResult.get("_id"), is(equalTo((Object)"42")));
}
您还可以将 Critiera.within
与 Circle
:
一起使用
@Test
public void serializePoinInCriteriaNearSphere() throws Exception {
... as above ...
Point p = new Point(-73, 40);
Circle circle = new Circle(p, new Distance(150.0, Metrics.KILOMETERS));
TypedAggregation<EventWithLocation> agg = newAggregation(EventWithLocation.class, //
match(where("eventTime").gte(1).and("location").withinSphere(circle)) //
, sort(Direction.DESC, "eventTime") //
, group("vanId").first(Aggregation.ROOT).as("first") //
);
... as above
}
我正在尝试使用 spring-data-mongodb 1.6.2 对一些 GPS 数据进行聚合查询。这是它的样子:
Aggregation agg = newAggregation(
match(new Criteria()
.andOperator(
Criteria.where("eventTime").gte(filterDate),
Criteria.where("location").nearSphere(p).maxDistance(distance)
)
),
sort(Direction.DESC, "vanId", "eventTime"),
group("vanId").first(Aggregation.ROOT).as("first")
);
return mongoTemplate.aggregate(agg,GpsDataEntity.MONGO_COLLECTION, GroupedEntity2.class);`
我看到的问题必须归因于查询的 match() 部分。异常真的很长,所以我只包含了堆栈,直到在上面的代码片段中调用 mongoTemplate.aggregate() 的点:
Caused by: java.lang.IllegalArgumentException: can't serialize class org.springframework.data.geo.Point at org.bson.BasicBSONEncoder._putObjectField(BasicBSONEncoder.java:284) at org.bson.BasicBSONEncoder.putObject(BasicBSONEncoder.java:185) at org.bson.BasicBSONEncoder._putObjectField(BasicBSONEncoder.java:240) at org.bson.BasicBSONEncoder.putObject(BasicBSONEncoder.java:185) at org.bson.BasicBSONEncoder._putObjectField(BasicBSONEncoder.java:240) at org.bson.BasicBSONEncoder.putObject(BasicBSONEncoder.java:199) at org.bson.BasicBSONEncoder._putObjectField(BasicBSONEncoder.java:240) at org.bson.BasicBSONEncoder.putObject(BasicBSONEncoder.java:185) at org.bson.BasicBSONEncoder._putObjectField(BasicBSONEncoder.java:240) at org.bson.BasicBSONEncoder.putObject(BasicBSONEncoder.java:185) at org.bson.BasicBSONEncoder._putObjectField(BasicBSONEncoder.java:240) at org.bson.BasicBSONEncoder.putIterable(BasicBSONEncoder.java:309) at org.bson.BasicBSONEncoder._putObjectField(BasicBSONEncoder.java:248) at org.bson.BasicBSONEncoder.putObject(BasicBSONEncoder.java:185) at org.bson.BasicBSONEncoder.putObject(BasicBSONEncoder.java:131) at com.mongodb.DefaultDBEncoder.writeObject(DefaultDBEncoder.java:33) at com.mongodb.OutMessage.putObject(OutMessage.java:289) at com.mongodb.OutMessage.writeQuery(OutMessage.java:211) at com.mongodb.OutMessage.query(OutMessage.java:86) at com.mongodb.DBCollectionImpl.find(DBCollectionImpl.java:81) at com.mongodb.DB.command(DB.java:317) at com.mongodb.DB.command(DB.java:296) at com.mongodb.DB.command(DB.java:371) at com.mongodb.DB.command(DB.java:243) at org.springframework.data.mongodb.core.MongoTemplate.doInDB(MongoTemplate.java:326) at org.springframework.data.mongodb.core.MongoTemplate.doInDB(MongoTemplate.java:324) at org.springframework.data.mongodb.core.MongoTemplate.execute(MongoTemplate.java:394) at org.springframework.data.mongodb.core.MongoTemplate.executeCommand(MongoTemplate.java:324) at org.springframework.data.mongodb.core.MongoTemplate.aggregate(MongoTemplate.java:1418) at org.springframework.data.mongodb.core.MongoTemplate.aggregate(MongoTemplate.java:1353)
如果我删除 nearSphere 条件,上述查询工作正常。我已经验证传递的点和距离是有效的。
如果有人能指出我做错了什么,我将不胜感激。
这不是 Spring 数据 MongoDB 中的错误。
实际上,$match 聚合表达式中不允许使用“$nearSphere”。 您必须改用 geoNear(..) - 请参阅下面的示例。
请注意 mongodb 要求 geoNear 是聚合管道中的第一个元素。
@Test
public void serializePoinInCriteriaNearSphere() throws Exception {
mongoTemplate.dropCollection(EventWithLocation.class);
mongoTemplate.insert(new EventWithLocation(3, new Point(-73.99408, 40.75057), "42"));
mongoTemplate.indexOps(EventWithLocation.class).ensureIndex(new GeospatialIndex("location"));
Point p = new Point(-73, 40);
NearQuery geoNear = NearQuery.near(p, Metrics.KILOMETERS).maxDistance(150.0);
TypedAggregation<EventWithLocation> agg = newAggregation(EventWithLocation.class, //
geoNear(geoNear, "distance") //
, match(where("eventTime").gte(1)) //
, sort(Direction.DESC, "eventTime") //
, group("vanId").first(Aggregation.ROOT).as("first") //
);
AggregationResults<DBObject> results = mongoTemplate.aggregate(agg, DBObject.class);
List<DBObject> list = results.getMappedResults();
DBObject firstResult = list.get(0);
assertThat(firstResult.get("_id"), is(equalTo((Object)"42")));
}
您还可以将 Critiera.within
与 Circle
:
@Test
public void serializePoinInCriteriaNearSphere() throws Exception {
... as above ...
Point p = new Point(-73, 40);
Circle circle = new Circle(p, new Distance(150.0, Metrics.KILOMETERS));
TypedAggregation<EventWithLocation> agg = newAggregation(EventWithLocation.class, //
match(where("eventTime").gte(1).and("location").withinSphere(circle)) //
, sort(Direction.DESC, "eventTime") //
, group("vanId").first(Aggregation.ROOT).as("first") //
);
... as above
}