【问题标题】:Return distinct and sorted query in AQL在 AQL 中返回不同且排序的查询
【发布时间】:2016-06-18 22:37:51
【问题描述】:

所以我有两个集合,一个包含具有一系列邮政编码作为属性的城市,另一个包含邮政编码及其纬度和经度。

我想返回离坐标最近的城市。使用地理索引这很容易,但我遇到的问题是多次返回同一个城市,有时它可能是第一个和第三个最接近的,因为我正在搜索与另一个城市接壤的邮政编码。

城市示例数据:

[
  {
    "_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"
  }
]

邮政编码示例数据:

[
  {
    "_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

【问题讨论】:

    标签: arangodb aql


    【解决方案1】:

    查询中的第一个FOR 将使用地理索引并可能返回少量文档(仅返回指定位置周围的邮政编码)。 第二个FOR 将为每个找到的邮政编码查找城市。这可能是个问题,具体取决于cities.postalCodescities.countryCode 上是否存在索引。如果不是,那么第二个FOR 必须在每次涉及cities 集合时对其进行全面扫描。这将是低效的。因此可能会像这样在两个属性上创建索引:

    db.cities.ensureIndex({ type: "hash", fields: ["countryCode", "postalCodes[*]"] });

    第三个FOR 可以在不是COLLECTc._id 而是被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) 来显示查询将使用哪些索引。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-16
      • 2010-09-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多