首页 文章

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

提问于
浏览
4

我需要有关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
  }
]

我想要一个查询,它将返回一个只包含第一个和最后一个项目的数组,即第一个日志条目和最新的日志条目:

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

2 回答

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

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

  • 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}
    

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

相关问题