gpt4 book ai didi

node.js - 按 $geonear 聚合

转载 作者:太空宇宙 更新时间:2023-11-04 00:31:27 24 4
gpt4 key购买 nike

我有一个看起来像这样的集合:

[
{
"roadname": "foo",
"data": [
{
"val": 50,
"loc": {
"type": "Point",
"coordinates": [3.197033554, 50.64611712]
}
}
},
{
"val": NULL,
"loc": {
"type": "Point",
"coordinates": [3.197740735, 50.6460058]
}
}
}
]
},
{
"roadname": "foo",
"data": [
{
"val": 50,
"loc": {
"type": "Point",
"coordinates": [3.32456512, 50.2744516]
}
}
}
]
},
{
"roadname": "bar",
"data": [
{
"val": 145,
"loc": {
"type": "Point",
"coordinates": [3.198408689, 50.64586985]
}
}
}
]
}
]

我在 map 上显示每个data.loc,这导致我发现: dispatched points 。 (点颜色代表 val 字段)

EDIT3:为了阐明我的数据库结构,这里是确切数据库的表示。每条灰线代表所提供数据集中的一个根元素: lines points

我想“对附近的点进行分组(使用data.loc),并且具有相同的父名称”,并聚合它们的val(为了简单起见,用平均值表示),以便显示如下内容: aggregated points

编辑3:重要的是要了解我试图聚合的点不共享任何共同的属性(property)或祖先。它们的唯一共同点是空间接近

我知道 neargeoneargroup 聚合,但我只是找不到解决方案来执行此操作。

我想使用纯 mongodb 解决方案。如果不可能,我也可以使用 turf.js 或其他库,但我只是在努力寻找一种可行且可扩展的方法来做到这一点。

<小时/>

编辑:集合上的主要根元素代表一条道路,因此道路上的所有点都具有相同的父roadname

<小时/>

EDIT2:可以找到数据 here

最佳答案

我认为这对你有用。我导入了你的数据集aggregatingpointsdata.json进入名为 roads 的 mongo 集合。

这就是 mongo 中一个集群的样子。因此,每个文档代表一个簇,或者是您提供的数据集中数组中的一个元素。需要记住的一件事是,只有当存在应分组在一起的一组点的某些标识符时,这才有效。在我的示例中,它是 _id

> db.roads.findOne()
{
"_id" : ObjectId("583ee50bd7c4d711d45c7757"),
"roadname" : "RD700",
"data" : [
{
"val" : null,
"loc" : {
"type" : "Point",
"coordinates" : [
3.197033554,
50.64611712
]
}
},
{
"val" : null,
"loc" : {
"type" : "Point",
"coordinates" : [
3.197740735,
50.6460058
]
}
},
{
"val" : 145,
"loc" : {
"type" : "Point",
"coordinates" : [
3.198408689,
50.64586985
]
}
},
]
}

这是您可以运行的 mongo 聚合,它将返回每个集群的平均值。我什至让它返回相同的 GeoJSON 格式。

db.roads.aggregate([
//unravel the cluster here
{ $unwind: "$data" },
//project the coordinates to more readable names while preserving roadname and GeoJSON type.
{ $project: {roadname: 1, type: "$data.loc.type", val : "$data.val", lng: { $arrayElemAt: ["$data.loc.coordinates",0]}, lat: { $arrayElemAt: ["$data.loc.coordinates",-1]}}},
//group on cluster id while preserving type and roadname. Take avergae of value, lat and long.
{ $group: { _id : "$_id", roadname: {$first:"$roadname"}, type: {$first: "$type"}, avgLng: { $avg: "$lng" },avgLat: { $avg: "$lat" }, avgVal: { $avg : "$val" }}},
//re-project to fit the similar format of original collection
{ $project: { _id: 1, roadname: 1, data : { val: "$avgVal", loc: {type : "$type", coordinates: ["$avgLng", "$avgLat"]}} }}
])

您还可以在聚合管道的末尾添加额外的 $out,以将所有这些平均质心移动到另一个更易于管理的集合。

这是上面所示的聚合管道调用后的结果。

[
{
"_id": ObjectId("583ee50bd7c4d711d45c775c"),
"roadname": "RD700",
"data": {
"val": 144.03703703703704,
"loc": {
"type": "Point",
"coordinates": [
3.2232721289257142,
50.67602178708569
]
}
}
},
{
"_id": ObjectId("583ee50bd7c4d711d45c775b"),
"roadname": "RD700",
"data": {
"val": 170.0344827586207,
"loc": {
"type": "Point",
"coordinates": [
3.22367598656322,
50.67626952408046
]
}
}
},
...
]

关于node.js - 按 $geonear 聚合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40806348/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com