是否可以使用 Ecto 和 MongoDB 进行地理空间查询?
Is it possible to make Geospatial queries with Ecto and MongoDB?
我正在开发一个 Phoenix 项目,该项目将 lat/lng 值存储在 MongoDB 中,并且需要使用 MongoDB 的内置 Geo 查询才能根据两点之间的距离查询记录。
我整个上午都在四处寻找,找到了针对 Postgres 的 this Geo repo。我宁愿不必切换到 Postgres,除非没有其他选择。
有没有人有 Ecto/MongoDB 和 Geo 查询的经验,可以给我指明正确的方向,或者知道 Ecto 目前是否可行?
一种可能的替代方法是使用 mongoose 设置一个简单的 nodejs 服务器来处理地理查询,然后在必要时让 Phoenix 切换到该服务?但如果有的话,我显然更喜欢基于 Ecto 的解决方案。
谢谢
保罗
它没有直接在 mongodb_ecto 中实现,但 Michał 说应该可以使用片段。
在 IRC 中,他写道:
something along the lines of where: fragment(foo: ["$geoWithin": [...]])
$geoWithin 被明确排除在原始作品之外...
https://github.com/michalmuskala/mongodb_ecto/issues/5
...并且没有出现在 NormalizedQuery 模块中
https://github.com/michalmuskala/mongodb_ecto/blob/master/lib/mongo_ecto/normalized_query.ex
另请注意,mongodb_ecto 仍需要 Ecto 1.0,因此您不能将其与 Ecto 2 beta 一起使用。
是的,这是可能的。您可以如前所述使用 fragment
。一个完整的例子可能会有帮助:
near_sphere = [
"$nearSphere": [
"$geometry": [
"type": "Point",
"coordinates": [10.0, 20.0]
],
"$maxDistance": 1000
]
]
from(c in City, where: fragment(location: ^near_sphere)
为了完成这项工作,您还需要为位置字段创建索引。根据文档,最好的方法是使用 GeoJSON 来存储位置,但您也可以使用 array:
defmodule MyApp.City do
# ...
schema "cities" do
field :location, {:array, :float}
end
end
然后你可以创建索引 execute/1
(https://hexdocs.pm/ecto/Ecto.Migration.html#execute/1)
def up do
execute [
createIndexes: "cities",
indexes: [
[
key: [location: "2dsphere"],
name: "location_2dsphere",
"2dsphereIndexVersion": 3
]
]
]
end
def down do
execute [
dropIndexes: "cities",
index: "location_2dsphere"
]
end
我正在开发一个 Phoenix 项目,该项目将 lat/lng 值存储在 MongoDB 中,并且需要使用 MongoDB 的内置 Geo 查询才能根据两点之间的距离查询记录。
我整个上午都在四处寻找,找到了针对 Postgres 的 this Geo repo。我宁愿不必切换到 Postgres,除非没有其他选择。
有没有人有 Ecto/MongoDB 和 Geo 查询的经验,可以给我指明正确的方向,或者知道 Ecto 目前是否可行?
一种可能的替代方法是使用 mongoose 设置一个简单的 nodejs 服务器来处理地理查询,然后在必要时让 Phoenix 切换到该服务?但如果有的话,我显然更喜欢基于 Ecto 的解决方案。
谢谢
保罗
它没有直接在 mongodb_ecto 中实现,但 Michał 说应该可以使用片段。
在 IRC 中,他写道:
something along the lines of
where: fragment(foo: ["$geoWithin": [...]])
$geoWithin 被明确排除在原始作品之外... https://github.com/michalmuskala/mongodb_ecto/issues/5
...并且没有出现在 NormalizedQuery 模块中 https://github.com/michalmuskala/mongodb_ecto/blob/master/lib/mongo_ecto/normalized_query.ex
另请注意,mongodb_ecto 仍需要 Ecto 1.0,因此您不能将其与 Ecto 2 beta 一起使用。
是的,这是可能的。您可以如前所述使用 fragment
。一个完整的例子可能会有帮助:
near_sphere = [
"$nearSphere": [
"$geometry": [
"type": "Point",
"coordinates": [10.0, 20.0]
],
"$maxDistance": 1000
]
]
from(c in City, where: fragment(location: ^near_sphere)
为了完成这项工作,您还需要为位置字段创建索引。根据文档,最好的方法是使用 GeoJSON 来存储位置,但您也可以使用 array:
defmodule MyApp.City do
# ...
schema "cities" do
field :location, {:array, :float}
end
end
然后你可以创建索引 execute/1
(https://hexdocs.pm/ecto/Ecto.Migration.html#execute/1)
def up do
execute [
createIndexes: "cities",
indexes: [
[
key: [location: "2dsphere"],
name: "location_2dsphere",
"2dsphereIndexVersion": 3
]
]
]
end
def down do
execute [
dropIndexes: "cities",
index: "location_2dsphere"
]
end