我有一个看起来像这样的集合:
[
{
"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]
}
}
}
]
}
]
我在地图上显示每个data.loc
,这导致我:
。 (点颜色代表val
字段)
EDIT3:为了阐明我的数据库结构,这里是确切数据库的表示。每个灰线表示来自提供的数据集的根元素:
我想“群组点靠近(使用data.loc
),并且拥有相同的父name
”,并汇总其val
(用平均值来说明这一点很简单),为了显示如下内容:
EDIT3:重要的是要了解我正在尝试聚合的内容不共享任何共同财产或祖先。他们的 ONLY 普通的denomitator是他们的空间接近度
我知道near
,geonear
和group
聚合,但我无法找到解决方案来执行此操作。
我想使用纯粹的mongodb解决方案。如果不可能,我也可以使用turf.js或其他库,但我只是在努力寻找一种可行且可扩展的方法来实现这一目标。
编辑:集合中的主要根元素代表道路,因此道路上的所有点都具有相同的父roadname
。
EDIT2 :可以找到数据 here
答案 0 :(得分:1)
我认为这对你有用。我将您的数据集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
]
}
}
},
...
]