无法序列化类org.springframework.data.geo.Point

时间:2015-04-10 05:32:26

标签: java spring mongodb spring-data-mongodb

我正在尝试使用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():

  

引起:java.lang.IllegalArgumentException:无法序列化类   org.springframework.data.geo.Point at   org.bson.BasicBSONEncoder._putObjectField(BasicBSONEncoder.java:284)     在org.bson.BasicBSONEncoder.putObject(BasicBSONEncoder.java:185)at   org.bson.BasicBSONEncoder._putObjectField(BasicBSONEncoder.java:240)     在org.bson.BasicBSONEncoder.putObject(BasicBSONEncoder.java:185)at   org.bson.BasicBSONEncoder._putObjectField(BasicBSONEncoder.java:240)     在org.bson.BasicBSONEncoder.putObject(BasicBSONEncoder.java:199)at   org.bson.BasicBSONEncoder._putObjectField(BasicBSONEncoder.java:240)     在org.bson.BasicBSONEncoder.putObject(BasicBSONEncoder.java:185)at   org.bson.BasicBSONEncoder._putObjectField(BasicBSONEncoder.java:240)     在org.bson.BasicBSONEncoder.putObject(BasicBSONEncoder.java:185)at   org.bson.BasicBSONEncoder._putObjectField(BasicBSONEncoder.java:240)     at org.bson.BasicBSONEncoder.putIterable(BasicBSONEncoder.java:309)     在   org.bson.BasicBSONEncoder._putObjectField(BasicBSONEncoder.java:248)     在org.bson.BasicBSONEncoder.putObject(BasicBSONEncoder.java:185)at   org.bson.BasicBSONEncoder.putObject(BasicBSONEncoder.java:131)at at   com.mongodb.DefaultDBEncoder.writeObject(DefaultDBEncoder.java:33)at 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 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 $ 1.doInDB(MongoTemplate.java:326)     在   org.springframework.data.mongodb.core.MongoTemplate $ 1.doInDB(MongoTemplate.java:324)     在   org.springframework.data.mongodb.core.MongoTemplate.execute(MongoTemplate.java:394)     在   org.springframework.data.mongodb.core.MongoTemplate.executeCommand(MongoTemplate.java:324)     在   org.springframework.data.mongodb.core.MongoTemplate.aggregate(MongoTemplate.java:1418)     在   org.springframework.data.mongodb.core.MongoTemplate.aggregate(MongoTemplate.java:1353)

如果我删除了nearSphere标准,上面的查询工作正常。我已经确认传递的Point和距离是有效的。

如果有人能对我做错了什么提出任何指示,我会很感激。

1 个答案:

答案 0 :(得分:0)

这不是Spring Data MongoDB中的错误。

实际上事实证明" $ nearSphere"不允许在$ match聚合表达式中。 您必须使用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.withinCircle

一起使用
@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
}