2017-11-20 16 views
4

ArangoDB AQL 쿼리에 대한 도움이 필요합니다. 부모 테이블 (Event)에 업데이트 세부 정보를 기록하는 트랜잭션 세부 정보 수집 (EventTran)이 있습니다. EventTran 속성은 timestamp 및 상위 _id_event에 대한 참조를 포함합니다. 나는 배열 첫 번째 및 마지막 (timestamp에 의해) EventTran 지정된 문서 id_event에 대한 배열을 반환하기 위해 노력하고있어. 다음 예는 다음과 같습니다ArangoDB AQL 쿼리의 첫 번째 항목과 마지막 항목을 얻는 방법

FOR event IN EventTran 
    FILTER event._id_event == "Event/167697" 
    SORT event.timestamp DESC 
    RETURN event 

는 반환 할 수 있습니다 :

[ 
    { 
    "_key": "214092", 
    "_id": "EventTran/214092", 
    "_id_event": "Event/167697", 
    "timestamp": 1511202637 
    }, 
    { 
    "_key": "213958", 
    "_id": "EventTran/213958", 
    "_id_event": "Event/167697", 
    "timestamp": 1511202542 
    }, 
    { 
    "_key": "191809", 
    "_id": "EventTran/191809", 
    "_id_event": "Event/167697", 
    "timestamp": 1511118705 
    }, 
    { 
    "_key": "167701", 
    "_id": "EventTran/167701", 
    "_id_event": "Event/167697", 
    "timestamp": 1510965562 
    } 
] 

내가 첫 번째 로그 항목 즉, 마지막 항목 배열을 반환하는 쿼리를 원하는 가장 최근의 로그 항목 :

[ 
    { 
    "_key": "214092", 
    "_id": "EventTran/214092", 
    "_id_event": "Event/167697", 
    "timestamp": 1511202637 
    }, 
    { 
    "_key": "167701", 
    "_id": "EventTran/167701", 
    "_id_event": "Event/167697", 
    "timestamp": 1510965562 
    } 
] 

답변

2

두 개의 p ossible 솔루션 : 당신이 볼 수 있듯이, 하나 개의 쿼리가 정렬 순서 DESC 다른 사용

RETURN [ 
    (FOR event IN EventTran 
    FILTER event._id_event == "Event/167697" 
    SORT event.timestamp DESC 
    LIMIT 1 
    RETURN event 
)[0], 
    (FOR event IN EventTran 
    FILTER event._id_event == "Event/167697" 
    SORT event.timestamp ASC 
    LIMIT 1 
    RETURN event 
)[0] 
] 

:

1) 첫 번째는 두 개의 쿼리를 실행하고 각에서 바로 위/아래 문서를 반환하는 것입니다 정렬 순서 ASC을 사용 중입니다. 각 쿼리에서 하나의 문서 만 반환되며 쿼리 당 해당 문서 만 반환됩니다. 지정한 _id_event 값과 일치하는 문서가 없으면 쿼리는 각각 null을 반환합니다. 따라서 전체 결과는 [null, null]이됩니다.

2) 대안은 그것에서 단지 첫 번째와 마지막 문서를 모든 단일 쿼리입니다 수행하고 반환하는 것입니다 :

LET results = (
    FOR event IN EventTran 
    FILTER event._id_event == "Event/167697" 
    SORT event.timestamp ASC 
    RETURN event 
) 
RETURN [ 
    results[0], 
    results[-1] 
] 

이 그러나 관련 이벤트에 대한 모든 문서는 (많은있을 수 있습니다 것)? 따라서 2 질의 솔루션이 더 효율적일 수 있습니다.

+0

도움을 주셔서 감사합니다. 분명히 트랜스가 상당히 많으므로 첫 번째 솔루션이 가장 좋습니다. –

4

다음은 의심 할 여지없이 모든 상황에서 가능한 최상의 해결책은 아니지만 SORT를 피할 수 있습니다. 컬렉션이 매우 작지 않은 한 가장 좋은 것은 입니다.

아이디어는 매우 간단합니다. 최소값과 최대 값을 결정한 다음 최소값을 수집하고 그 중 하나를 선택하고 최대 값과 마찬가지로 선택하십시오.

LET mnmx = (
    FOR x in EventTran 
    FILTER event._id_event == "Event/167697" 
    COLLECT AGGREGATE mn = MIN(x.timestamp), mx = MAX(x.timestamp) 
    RETURN {mn,mx}) 

LET mn = mnmx.mn 
LET mx = mnmx.mx 

LET least = (
    FOR x in EventTran 
    FILTER x.timestamp == mn 
    COLLECT y=x INTO minimal 
    RETURN minimal[0]) 

LET greatest = (
    FOR x in EventTran 
    FILTER x.timestamp == mx 
    COLLECT y=x INTO maximal 
    RETURN maximal[0]) 

RETURN {least, greatest} 

마지막 라인의 약어입니다 { "적어도"적어도, "큰"큰}, leastgreatest은 최소와 최대의 타임 스탬프와 항목 인.

+1

이 쿼리는 @stj가 표시 한 첫 번째 쿼리에 대해 '_id_event, timestamp'에 skiplist 인덱스를 사용할 수 없지만'COLLECT AGGREGATE '로 수행 할 수있는 작업에 대한 흥미로운 데모입니다. – CoDEmanX