MongoDB地理查询前如何反转存储错误的坐标?
解决MongoDB坐标顺序错误导致的地理查询问题
下面提供三个可行方案,无需修改数据库中的坐标即可完成地理范围判断:
方案1:聚合管道内修正坐标后查询
先过滤非地理条件的数据,再反转坐标格式,最后执行地理相交查询,能有效减少后续处理的数据量:
db.users.aggregate([ // 先过滤时间和用户ID,缩小处理范围 { $match: { datetime: { $gte: ISODate("2022-12-25T00:00:00.126+0000"), $lte: ISODate("2023-01-27T11:00:00.126+0000") }, user_id: { $in: ["a2UxA9ysCQlk8XdYNToT5"] } } }, // 反转存储的坐标顺序,生成符合规范的字段 { $addFields: { correctedLocation: { $reverseArray: "$location" } } }, // 用修正后的坐标执行地理相交判断 { $match: { correctedLocation: { $geoIntersects: { $geometry: { type: "Polygon", coordinates: [[ [55.04656085673112, 24.97153076104319], [55.05205402079362, 24.97545995358559], [55.057633015544596, 24.974176171805773], [55.06005773249406, 24.971958698993816], [55.05246171656388, 24.96530604075661], [55.04656085673112, 24.97153076104319] ]] } } } } }, // 可选:移除临时生成的修正字段 { $project: { correctedLocation: 0 } } ])
方案2:反转查询多边形的坐标
直接修改查询条件中的多边形坐标顺序,让它和数据库存储的格式匹配,无需使用聚合管道,写法更简洁:
db.getCollection("users").find({ $and: [ { datetime: { $gte: ISODate("2022-12-25T00:00:00.126+0000") } }, { datetime: { $lte: ISODate("2023-01-27T11:00:00.126+0000") } }, { user_id: { $in: ["a2UxA9ysCQlk8XdYNToT5"] } }, { location: { $geoIntersects: { $geometry: { type: "Polygon", coordinates: [[ // 反转每个坐标点的顺序,匹配数据库存储格式 [24.97153076104319, 55.04656085673112], [24.97545995358559, 55.05205402079362], [24.974176171805773, 55.057633015544596], [24.971958698993816, 55.06005773249406], [24.96530604075661, 55.05246171656388], [24.97153076104319, 55.04656085673112] ]] } } } } ] })
方案3:创建自动修正坐标的视图
如果需要频繁执行这类查询,可以创建一个视图,自动反转坐标,后续查询视图时直接使用正常地理语法:
- 创建视图
db.createView("users_corrected", "users", [ { $addFields: { location: { $reverseArray: "$location" } } } ])
- 查询视图(和正常集合查询语法一致)
db.getCollection("users_corrected").find({ $and: [ { datetime: { $gte: ISODate("2022-12-25T00:00:00.126+0000") } }, { datetime: { $lte: ISODate("2023-01-27T11:00:00.126+0000") } }, { user_id: { $in: ["a2UxA9ysCQlk8XdYNToT5"] } }, { location: { $geoIntersects: { $geometry: { type: "Polygon", coordinates: [[ [55.04656085673112, 24.97153076104319], [55.05205402079362, 24.97545995358559], [55.057633015544596, 24.974176171805773], [55.06005773249406, 24.971958698993816], [55.05246171656388, 24.96530604075661], [55.04656085673112, 24.97153076104319] ]] } } } } ] })
内容的提问来源于stack exchange,提问作者FR STAR
相关产品推荐
相关产品推荐

