我在MongoDB中有一个集合,其中有一个名为“ geometry” 的字段,其纬度和经度是这样的:
{
"abc":"xyz",
"geometry" : [
{
"lat" : 45.0,
"lng" : 25.0
},
{
"lat" : 46.0,
"lng" : 26.0
}
]
}
我想将字段 geometry 转换为类似这样的格式,以符合GeoJSON格式:
{
"abc":"xyz",
"geometry": {
"type": "LineString",
"coordinates": [
[
25.0,
45.0
],
[
26.0,
46.0
]
]
}
}
本质上,该操作涉及获取具有两个K / V对的对象数组,并仅选择值并将它们存储为数组数组(顺序相反-因此,值“ lng”排在最前面)。
我的尝试失败: 我尝试使用聚合并尝试投影以下内容:
"geometry": {"type":"LineString", "coordinates":["$points.lng","$points.lat"] }
给我的结果类似于:
"geometry": {
"type": "LineString",
"coordinates": [
[
25.0,
26.0
],
[
45.0,
46.0
]
]
}
我尝试使用此方法并逐条记录修改数据记录,但是结果不一致。而且,我试图避免遍历每条记录并一一更改结构。有办法有效地做到这一点吗?
答案 0 :(得分:1)
您认为以下代码应从理论上讲起作用:
db.collection.aggregate({
$project: {
"abc": 1, // include the "abc" field in the output
"geometry": { // add a new geometry sub-document
"type": "LineString", // with the hardcoded "type" field
"coordinates": {
$map: {
"input": "$geometry", // transform each item in the "geometry" array
"as": "this",
"in": [ "$$this.lng", "$$this.lat" ] // into an array of values only, ith "lng" first, "lat" second
}
}
}
}
}, {
$out: "result" // creates a new collection called "result" with the transformed documents in it
})
但是,根据SERVER-37635,MongoDB在此阶段的工作方式是上述查询产生了令人惊讶的输出,其中coordinates
字段多次包含所需结果。因此,以下查询可用于生成所需的输出:
db.collection.aggregate({
$addFields: {
"abc": 1,
"geometry2": {
"type": "LineString",
"coordinates": {
$map: {
"input": "$geometry",
"as": "this",
"in": [ "$$this.lng", "$$this.lat" ]
}
}
}
}
}, {
$project: {
"abc": 1,
"geometry": "$geometry2"
}
}, {
$out: "result"
})
在上述JIRA故障单的注释部分中,Charlie Swanson提到了另一种解决方法,该解决方法使用$let
“欺骗” MongoDB以所需的方式解释查询。我在此处重新发布(请注意,它缺少$out
部分):
db.collection.aggregate([
{
$project: {
"abc": 1,
"geometry": {
$let: {
vars: {
ret: {
"type": "LineString",
"coordinates": {
$map: {
"input": "$geometry",
"as": "this",
"in": [
"$$this.lng",
"$$this.lat"
]
}
}
}
},
in: "$$ret"
}
}
}
}
])