Усекать и считать позиции весной с Mongodb - PullRequest
0 голосов
/ 11 октября 2018

В моем приложении я хочу отобразить тепловую карту, поэтому мне нужно что-то подобное для ее построения:

data: [{lat: 24.6408, lng:46.7728, count: 3},{lat: 50.75, lng:-1.55, count: 1}, ...]

У меня есть:

@Document(collection = "positions")
public class Position {
    @Id
    private String id;
    private long timestamp;
    @GeoSpatialIndexed(type = GeoSpatialIndexType.GEO_2DSPHERE)
    private GeoJsonPoint location;
    private File file;

Для того, чтобы сосчитать и сгруппироватьпозиции, которые действительно близки, я думал об обрезании всех позиций, а затем сгруппировал их для подсчета.Так, например:

{"type" : "Point", "coordinates": [-47.121311,-18.151512]}
{"type" : "Point", "coordinates": [-47.121312,-18.151523]}
{"type" : "Point", "coordinates": [-47.121322,-18.151533]}

Результат: {"type" : "Point, "coordinates" : [-47.1213,-18.1515]}, "count" : 3}

В оболочке это будет что-то вроде:

"$map": {
          "input": '$location.coordinates',
          "in": {
            "$divide": [
              { "$trunc": { "$multiply": [ '$$this', 10000 ] } },
              10000
            ]                
          }
}

И тогда я сгруппирую по location.coordinates.Но я не знаю, является ли это правильным подходом, а также я не знаю, как написать этот код в Spring внутри моего PositionRepositoryCustom.Я должен был бы создать Агрегацию, «сделать карту», ​​а затем группу для подсчета.

Большое спасибо.

---- РЕДАКТИРОВАТЬ 2 ---: Я создалкласс называется:

public class PositionSummary {

    private List<Double> coordinates;
    private Double count;

    public PositionSummary() { }

    public List<Double> getCoordinates() {
        return coordinates;
    }

    public void setCoordinates(List<Double> coordinates) {
        this.coordinates = coordinates;
    }

    public Double getCount() {
        return count;
    }

    public void setCount(Double count) {
        this.count = count;
    }
}

И моя ИСПРАВЛЕННАЯ функция AggregatePositions ():

@Override
public List<PositionSummary> AggregatePositionss() {

    AggregationOperation project =

            Aggregation.project("location")
                    .and( VariableOperators.mapItemsOf("location.coordinates").
                                    as("coord").
                                    andApply(
                                            ArithmeticOperators.valueOf(
                                                    ArithmeticOperators.valueOf(
                                                            ArithmeticOperators.valueOf(
                                                                    "$$coord"
                                                            ).multiplyBy(1000)
                                                    ).trunc()
                                            ).divideBy(1000)
                                    ))
                                    .as("coordinates");

    AggregationOperation group =
            Aggregation.group("coordinates")
                    .count().as("count");

    Aggregation agg = Aggregation.newAggregation(project,group);

    //AggregationResults<PositionSummary> groupResults = mongoTemplate.aggregate(agg, Position.class, PositionSummary.class);

    AggregationResults<PositionSummary> groupResults = mongoTemplate.aggregate(agg, "positions", PositionSummary.class);

    List<PositionSummary> result = groupResults.getMappedResults();


    return result;
}

И я получаю:

[
    {
        "coordinates": null,
        "count": 1
    },
    {
        "coordinates": null,
        "count": 1
    },
    {
        "coordinates": null,
        "count": 2
    },
    {
        "coordinates": null,
        "count": 1
    },
    {
        "coordinates": null,
        "count": 2
    },
...]

Еще раз спасибо.

1 Ответ

0 голосов
/ 11 октября 2018

Ваш подход в порядке.Используйте приведенный ниже код агрегации.

AggregationOperation project1 = 
         Aggregation.project("type")        
             .and(
                VariableOperators.mapItemsOf("location.coordinates").
                   as("coord").
                   andApply(
                    ArithmeticOperators.valueOf(
                      ArithmeticOperators.valueOf(         
                        ArithmeticOperators.valueOf(
                          "$$coord"
                        ).multiplyBy(1000)
                      ).trunc()
                    ).divideBy(1000)
                  )
             .as("coordinates");

AggregationOperation group = 
         Aggregation.group("coordinates")   
            .first("type").as("type")   
            .count().as("count");

AggregationOperation project2 = Aggregation.project("count","type").andExclude("_id").andInclude(Fields.from(Fields.field("coordinates", "_id")));

Aggregation agg = Aggregation.newAggregation(project1,group,project2);

List<Document> results = mongoTemplate.aggregate(agg,"positions",Document.class).getMappedResults();
...