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

Posted

技术标签:

【中文标题】如何在 ArangoDB AQL 查询中获取第一个和最后一个条目【英文标题】:How to get first and last entries in an ArangoDB AQL query 【发布时间】:2017-11-20 19:10:52 【问题描述】:

我需要有关 ArangoDB AQL 查询的帮助。我有一个事务详细信息集合 (EventTran),它在其父表 (Event) 上记录更新详细信息。 EventTran 属性包括timestamp 和对父_id_event 的引用。我正在尝试制定一个查询以返回一个数组,该数组为指定的id_event 的第一个和最后一个(timestampEventTran 文档。这是一个例子:

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
  
]

我想要一个返回数组的查询,只有 firstlast 项,即第一个日志条目,以及最近的日志条目:

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

【问题讨论】:

【参考方案1】:

以下无疑不是最好的解决方案 情况,但它确实避免了排序,这可能是最后一件事 除非集合非常小,否则您想这样做。

这个想法很简单:确定最小值和最大值,然后收集最小的项目并从中选择一个,对于最大的项目也是如此。

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": best 的缩写,leastgreatest时间戳最小和最大的项目。

【讨论】:

虽然这个查询不能使用_id_event,timestamp 上的跳过列表索引来处理@stj 显示的第一个查询,但它是一个有趣的演示,可以用COLLECT AGGREGATE 完成什么。【参考方案2】:

有两种可能的解决方案:

1) 第一个是执行两个查询并只返回每个查询的顶部/底部文档:

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。每个查询仅返回一个文档,并且每个查询仅返回该文档。 如果指定的_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]
]

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

【讨论】:

感谢您的帮助!!肯定会有不少反式,所以第一个解决方案听起来最好。

以上是关于如何在 ArangoDB AQL 查询中获取第一个和最后一个条目的主要内容,如果未能解决你的问题,请参考以下文章

使用AQL进行图形查询

Arangodb AQL 连接、合并、嵌入嵌套的三个或更多集合

ArangoDB AQL 深度数组扫描

ArangoDB图数据库--总参

ArangoDb - 如何在限制过滤结果之前计算过滤结果的数量

Arango db 快速入门