2016-06-18 5 views
2

그래서 두 개의 콜렉션이 있습니다. 하나는 속성으로 우편 번호 배열이 있고 다른 하나는 우편 번호와 위도가 & 경도입니다.AQL의 별개의 정렬 된 쿼리

좌표에 가장 가까운 도시를 반환하고 싶습니다. 이것은 지리적 색인으로는 쉽지만, 내가 가지고있는 문제는 동일한 도시가 여러 번 반환되는 것과 몇 번에 걸쳐 다른 도시와 접하는 우편 번호이기 때문에 가장 가까운 도시 일 수 있습니다.

도시 예제 데이터 :

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

답변

2

쿼리의 첫 번째 FOR은 아마도 몇 가지 문서 (지정된 위치 주변의 우편 번호 만)를 반환 할 것입니다. 두 번째 FOR은 발견 된 각 우편 번호에 대해 도시를 검색합니다. cities.postalCodescities.countryCode에 색인이 있는지 여부에 따라 문제가 될 수 있습니다. 그렇지 않은 경우 두 번째 FOR은 관련된 때마다 cities 컬렉션의 전체 검사를 수행해야합니다. 이것은 비효율적이다.

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 때되지 COLLECT ING c._id이 아니라 c 의해 완전히 제거 될 수

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

: 따라서, 이와 같은 두 개의 속성에 대한 인덱스를 생성 할 수있다 쿼리 문자열,하지만 제 생각 엔 효율성을 많이 도움이되지 않을 수도 있습니다. 세 번째 FOR은 O (1) 인 도시 문서를 찾기 위해 기본 인덱스를 사용합니다.

일반적으로 인덱스를 사용하는 쿼리에 대해 의심이가는 경우 db._explain(queryString)을 사용하여 쿼리에서 사용할 인덱스를 표시 할 수 있습니다.