如何获取 ArangoDB AQL 查询中的第一个和最后一个条目

How to get first and last entries in an ArangoDB AQL query

我需要有关 ArangoDB AQL 查询的帮助。我有一个事务详细信息集合 (EventTran),用于记录其父项 table (Event) 的更新详细信息。 EventTran 属性包括 timestamp 和对父 _id_event 的引用。我正在尝试查询 return 一个 只有 的第一个和最后一个(按 timestampEventTran 个文档的数组id_event。这是一个例子:

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

可能 return:

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

我想要一个查询,它将 return 一个数组 只有 firstlast 项,即第一个日志条目和最近的日志条目:

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

有两种可能的解决方案:

1) 第一个是执行两个查询,return 只是每个查询的 top/bottom 文档:

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]
]

如您所见,一个查询使用排序顺序 DESC,另一个查询使用排序顺序 ASC。每个查询只 returned 一个文档,每个查询只 returned 那个文档。 如果指定的 _id_event 值没有匹配的文档,则每个查询将 return null。所以整体结果会变成[null, null].

2) 另一种方法是只做一个查询,return 只是其中的第一个和最后一个文档:

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

然而,这将包含关联事件的所有文档(可能很多?),因此双查询解决方案可能更有效。

以下无疑不是所有可能的最佳解决方案 情况下,但它确实避免了 SORT,这可能是最后一件事 除非集合很小,否则你想做。

思路很简单:确定最小值和最大值,然后收集最小项和select其中之一,同样收集最大项。

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}

最后一行是 {"least": least, "greatest": greatest} 的缩写,leastgreatest 是时间戳最少和最大的项目.