使用 Mongodb 在 Spring 中截断和计算位置
Posted
技术标签:
【中文标题】使用 Mongodb 在 Spring 中截断和计算位置【英文标题】:Truncate and count positions in Spring with Mongodb 【发布时间】:2019-03-15 23:00:10 【问题描述】:在我的应用程序中,我想显示一个热图,所以我需要这样的东西来构建它:
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
在shell中它会是这样的:
"$map":
"input": '$location.coordinates',
"in":
"$divide": [
"$trunc": "$multiply": [ '$$this', 10000 ] ,
10000
]
然后我会按location.coordinates
分组。但我不知道这是否是正确的方法,也不知道在我的 PositionRepositoryCustom 中的 Spring 中编写此代码。我必须创建一个聚合,“绘制地图”,然后计算组。
非常感谢。
----编辑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;
而我的 CORRECTED 函数 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】:你的方法很好。使用以下聚合代码。
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();
【讨论】:
感谢您的回复,感谢您抽出宝贵时间。我用我所做的更新了我的答案,如果可以请检查一下,谢谢。 不客气。你能试试AggregationResults<PositionSummary> groupResults = mongoTemplate.aggregate(agg, "positions", PositionSummary.class);
变种吗?
我按照你说的做了改变,但现在我得到了空坐标。我又更新了!谢谢
不客气。这是意料之中的。更新了答案以包括项目阶段。
我添加了新的项目阶段,现在确实可以使用了,非常感谢 Veeram!我觉得这个主题很困难,而且我没有找到很多示例和文档,因此非常感谢您的帮助。以上是关于使用 Mongodb 在 Spring 中截断和计算位置的主要内容,如果未能解决你的问题,请参考以下文章
MongoDB Sink 连接器:Apache Kafka 中的消息被截断
使用 Spring 的 @Value 注释插入时如何避免截断前导零数字?