Return AQL 中不同且排序的查询
Return distinct and sorted query in AQL
所以我有两个集合,一个包含一系列邮政编码的城市 属性,另一个包含邮政编码及其纬度和经度。
我想return距离坐标最近的城市。使用地理索引这很容易,但我遇到的问题是同一个城市被 return 多次编辑,有时它可能是第一和第三最近的,因为我正在搜索的邮政编码接壤另一个城市。
城市示例数据:
[
{
"_key": "30936019",
"_id": "cities/30936019",
"_rev": "30936019",
"countryCode": "US",
"label": "Colorado Springs, CO",
"name": "Colorado Springs",
"postalCodes": [
"80904",
"80927"
],
"region": "CO"
},
{
"_key": "30983621",
"_id": "cities/30983621",
"_rev": "30983621",
"countryCode": "US",
"label": "Manitou Springs, CO",
"name": "Manitou Springs",
"postalCodes": [
"80829"
],
"region": "CO"
}
]
postalCodes 示例数据:
[
{
"_key": "32132856",
"_id": "postalCodes/32132856",
"_rev": "32132856",
"countryCode": "US",
"location": [
38.9286,
-104.6583
],
"postalCode": "80927"
},
{
"_key": "32147422",
"_id": "postalCodes/32147422",
"_rev": "32147422",
"countryCode": "US",
"location": [
38.8533,
-104.8595
],
"postalCode": "80904"
},
{
"_key": "32172144",
"_id": "postalCodes/32172144",
"_rev": "32172144",
"countryCode": "US",
"location": [
38.855,
-104.9058
],
"postalCode": "80829"
}
]
以下查询有效,但作为 ArangoDB 新手,我想知道是否有更有效的方法来执行此操作:
FOR p IN WITHIN(postalCodes, 38.8609, -104.8734, 30000, 'distance')
FOR c IN cities
FILTER p.postalCode IN c.postalCodes AND c.countryCode == p.countryCode
COLLECT close = c._id AGGREGATE distance = MIN(p.distance)
FOR c2 IN cities
FILTER c2._id == close
SORT distance
RETURN c2
查询中的第一个 FOR
将使用地理索引和可能 return 几个文档(只是指定位置周围的邮政编码)。
第二个 FOR
将查找每个找到的邮政编码所在的城市。这可能是一个问题,具体取决于 cities.postalCodes
和 cities.countryCode
上是否存在索引。如果不是,则第二个 FOR
每次涉及时都必须对 cities
集合进行全面扫描。这将是低效的。因此,它可能会像这样在两个属性上创建索引:
db.cities.ensureIndex({ type: "hash", fields: ["countryCode", "postalCodes[*]"] });
第三个 FOR
可以完全删除,而不是 c._id
COLLECT
而是 c
:
FOR p IN WITHIN(postalCodes, 38.8609, -104.8734, 30000, 'distance')
FOR c IN cities
FILTER p.postalCode IN c.postalCodes AND c.countryCode == p.countryCode
COLLECT city = c AGGREGATE distance = MIN(p.distance)
SORT distance
RETURN city
这将缩短查询字符串,但我认为这可能对效率没有太大帮助,因为第三个 FOR
将使用主索引查找城市文档,这是 O(1)。
一般来说,当对使用索引的查询有疑问时,可以使用 db._explain(queryString)
来显示查询将使用哪些索引。
所以我有两个集合,一个包含一系列邮政编码的城市 属性,另一个包含邮政编码及其纬度和经度。
我想return距离坐标最近的城市。使用地理索引这很容易,但我遇到的问题是同一个城市被 return 多次编辑,有时它可能是第一和第三最近的,因为我正在搜索的邮政编码接壤另一个城市。
城市示例数据:
[
{
"_key": "30936019",
"_id": "cities/30936019",
"_rev": "30936019",
"countryCode": "US",
"label": "Colorado Springs, CO",
"name": "Colorado Springs",
"postalCodes": [
"80904",
"80927"
],
"region": "CO"
},
{
"_key": "30983621",
"_id": "cities/30983621",
"_rev": "30983621",
"countryCode": "US",
"label": "Manitou Springs, CO",
"name": "Manitou Springs",
"postalCodes": [
"80829"
],
"region": "CO"
}
]
postalCodes 示例数据:
[
{
"_key": "32132856",
"_id": "postalCodes/32132856",
"_rev": "32132856",
"countryCode": "US",
"location": [
38.9286,
-104.6583
],
"postalCode": "80927"
},
{
"_key": "32147422",
"_id": "postalCodes/32147422",
"_rev": "32147422",
"countryCode": "US",
"location": [
38.8533,
-104.8595
],
"postalCode": "80904"
},
{
"_key": "32172144",
"_id": "postalCodes/32172144",
"_rev": "32172144",
"countryCode": "US",
"location": [
38.855,
-104.9058
],
"postalCode": "80829"
}
]
以下查询有效,但作为 ArangoDB 新手,我想知道是否有更有效的方法来执行此操作:
FOR p IN WITHIN(postalCodes, 38.8609, -104.8734, 30000, 'distance')
FOR c IN cities
FILTER p.postalCode IN c.postalCodes AND c.countryCode == p.countryCode
COLLECT close = c._id AGGREGATE distance = MIN(p.distance)
FOR c2 IN cities
FILTER c2._id == close
SORT distance
RETURN c2
查询中的第一个 FOR
将使用地理索引和可能 return 几个文档(只是指定位置周围的邮政编码)。
第二个 FOR
将查找每个找到的邮政编码所在的城市。这可能是一个问题,具体取决于 cities.postalCodes
和 cities.countryCode
上是否存在索引。如果不是,则第二个 FOR
每次涉及时都必须对 cities
集合进行全面扫描。这将是低效的。因此,它可能会像这样在两个属性上创建索引:
db.cities.ensureIndex({ type: "hash", fields: ["countryCode", "postalCodes[*]"] });
第三个 FOR
可以完全删除,而不是 c._id
COLLECT
而是 c
:
FOR p IN WITHIN(postalCodes, 38.8609, -104.8734, 30000, 'distance')
FOR c IN cities
FILTER p.postalCode IN c.postalCodes AND c.countryCode == p.countryCode
COLLECT city = c AGGREGATE distance = MIN(p.distance)
SORT distance
RETURN city
这将缩短查询字符串,但我认为这可能对效率没有太大帮助,因为第三个 FOR
将使用主索引查找城市文档,这是 O(1)。
一般来说,当对使用索引的查询有疑问时,可以使用 db._explain(queryString)
来显示查询将使用哪些索引。