arrays - 如何将字段(具有 K-V 对的对象数组)转换为仅具有值的数组数组?

标签 arrays mongodb aggregation-framework pymongo geojson

我在 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
                ]
            ]                
        }

我试过使用它并逐条修改数据记录,但结果并不一致。而且,我试图避免逐一检查每条记录并逐一更改结构。有没有办法有效地做到这一点?

最佳答案

您会认为以下代码理论上应该可以工作:

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"
        }
      }
    }
  }
])

关于arrays - 如何将字段(具有 K-V 对的对象数组)转换为仅具有值的数组数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52822254/

相关文章:

javascript - 自定义排序函数如何用于多维数组

c++ - 在两个进程之间共享数组

javascript - 如何在页面刷新时随机交换图像横幅?

mongodb - 如何为 HWIOAuthBundle 编写用户提供程序

node.js - 限制 mongoDB 聚合中不同类型结果的数量

c++ - 不同类型数组的不同行为

android - com.parse.ParseRequest$ParseRequestException : bad json response (When I moved parse server to Heroku) 错误

node.js - $lookup 嵌套对象数组

mongodb - 比较数组并返回差异

java - 如何在吗啡中进行聚合?