gpt4 book ai didi

MongoDB - $geoNear 在同一文档中有多个匹配项

转载 作者:行者123 更新时间:2023-12-02 17:26:30 24 4
gpt4 key购买 nike

我有一个看起来像这样的集合:

{
"_id" : ObjectId("5783051796a90cd8098fc3e0"),
"name" : "Org 1",
"locations" : [
{
"name" : "loc 1",
"_id" : ObjectId("57831ac2febcceaf173e81ab"),
"address" : {
"coordinates" : [
172.6034932,
-43.5333797
]
}
},
{
"name" : "loc 2",
"_id" : ObjectId("5783436dc57b8d6248c9c196"),
"address" : {
"coordinates" : [
172.6034977,
-43.5335158
]
}
},
{
"name" : "loc 3",
"_id" : ObjectId("5783439bc57b8d6248c9c197"),
"address" : {
"coordinates" : [
168.6626435,
-45.0311622
]
}
}
]
}

locations.address.coordinates 上有一个 2dsphere 索引

我正在使用 aggreagategeonear 来查询这些文档:

db.organisations.aggregate([
{
$geoNear: {
near: { type: "Point", coordinates: [ 172.6036799 , -43.5335639 ] },
distanceField: "dist.calculated",
maxDistance: 5,
includeLocs: "dist.location",
num: 5,
limit: 200,
spherical: true
}
}
])

此聚合工作正常,我得到了所选区域中至少有 1 个位置的所有文档。问题是,当 1 个文档中有超过 1 个匹配项时,我只想检索相关位置。

MongoDB 能够通过 includeLocs 选项告诉我哪个是最接近的,但这还不够,因为我想要所有详细信息。

至少,如果我有每个位置的距离,我可以稍后在聚合管道上对其进行过滤。使用 distanceField 选项我可以获得整个文档的距离,但不是每个匹配位置的距离

回顾一下:我的目标是找到所有具有至少 1 个匹配位置的文档,并知道位置数组中哪些是相关位置。

有没有办法得到它,还是我对 Mongo 的要求太多了?

最佳答案

鉴于澄清,完全重写了答案。

你是对的,$geoNear必须是第一阶段。解决方法是使用“$unwind”和“$redact”将geoNear提供的匹配位置文档与对应的数组元素进行比较。

测试数据:

db.test.insert({ "locs" : [ 
{ "name" : "a", "address" : { "type" : "Point", "coordinates" : [ 0, 0 ] } },
{ "name" : "b", "address" : { "type" : "Point", "coordinates" : [ 1, 1 ] } },
{ "name" : "c", "address" : { "type" : "Point", "coordinates" : [ 2, 2 ] } }
]})

db.test.insert({ "locs" : [
{ "name" : "h", "address" : { "type" : "Point", "coordinates" : [ 1.01, 1.01 ] } }
]})

db.test.ensureIndex( { "locs.address" : "2dsphere" } )

查询:

db.test.aggregate([
{ "$geoNear" : { near : { "type" : "Point", "coordinates" : [ 1, 1 ] }, distanceField: "dist.calculated", maxDistance: 5000, includeLocs: "dist.location", num: 5, limit: 200, spherical: true } },
{ "$unwind" : "$locs" },
{ "$redact" : {
"$cond" : {
if : { "$eq" : [ { "$cmp" : [ "$locs.address", "$dist.location" ] }, 0 ] },
then : "$$KEEP",
else : "$$PRUNE"
}
}
}
])

geoNear 阶段将输出带有显示距离和匹配位置字段的“dist”字段的整个文档:

{ 
"_id" : ObjectId("5786fa0ddeb382a191a43122"),
"locs" : [ { "name" : "h", "address" : { "type" : "Point", "coordinates" : [ 1.01, 1.01 ] } } ],
"dist" : {
"calculated" : 0,
"location" : { "type" : "Point", "coordinates" : [ 1, 1 ] }
}
}

我们$unwind “locs”数组允许访问单个数组元素。 dist 字段被保留。

$redact然后可以使用字段删除地址与 $geoNear 阶段返回的位置不匹配的任何数组元素。

结果:

{ 
"_id" : ObjectId("5786fa0ddeb382a191a43121"),
"locs" : { "name" : "b", "address" : { "type" : "Point", "coordinates" : [ 1, 1 ] } },
"dist" : { "calculated" : 0, "location" : { "type" : "Point", "coordinates" : [ 1, 1 ] } }
}
{
"_id" : ObjectId("5786fa0ddeb382a191a43122"),
"locs" : { "name" : "h", "address" : { "type" : "Point", "coordinates" : [ 1.01, 1.01 ] } },
"dist" : { "calculated" : 1574.1651198970692, "location" : { "type" : "Point", "coordinates" : [ 1.01, 1.01 ] } }
}

更广泛地说,您可能需要考虑调整数据模型,以便每个文档只包含一个地理空间点。 geoNear提供的距离数据好像只针对单个文档,所以以后如果要按多个文档过滤可能会有问题。

关于MongoDB - $geoNear 在同一文档中有多个匹配项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38339995/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com