【问题标题】:ArangoDB Getting the Index of a DocumentArangoDB 获取文档的索引
【发布时间】:2015-11-20 17:20:42
【问题描述】:

有没有办法在 ArangoDB 中获取特定文档的索引,以便在 LIMIT 操作中使用它?例如,假设我通过它的 ID 查找一个 Document,发现它的索引是 534,那么我会这样使用它:

LIMIT 534, 30

...并在我查找的文档之后返回接下来的 30 个文档。但是,我似乎找不到使用 AQL 获取文档索引的方法...

【问题讨论】:

    标签: indexof arangodb aql


    【解决方案1】:

    问题是下一个文档应该是什么意思。

    如果这里的next表示文档键索引顺序

    文档在集合中没有特定的“顺序”或“索引”。集合中的文档在未排序的主索引中由它们的 _key / _id 属性组织。

    要获取下一个文档键(假设按字典顺序排序键),必须读取集合的所有键,对它们进行排序,然后以某种方式找到当前文档的索引以获取下一个键。这将是非常低效的。

    集合上的其他索引是可选的,因此不能依赖它们存在并且可用于此类查询。

    如果这里的 next 表示插入或更新顺序,那么也没有明智的方法来获取 next 文档。

    一种解决方法可能是在某些文档属性上使用排序(即跳过列表)索引,理想情况下是唯一的索引,并在每当插入文档时填充它(如果更新也应该更改 order 文件)。

    然后要查找下一个文档,请执行以下操作:

    • 首先通过_id_key找到所需的文档并将文档数据提取到应用程序中

    • 获取具有排序索引的文档属性,并在后续 AQL 查询中使用它,如下所示

    这将允许您找到原始文档之后的文档,但是,您必须以某种方式维护 order 属性:

    FOR doc IN collection
      FILTER doc.`order` > @value
      LIMIT 0, 30
      RETURN doc
    

    如果您的文档有一些可用于排序的属性,这将很容易做到,但如果它们没有这样的属性,这将是一个笨拙的解决方案。

    【讨论】:

    • 问题是我按不同的(并不总是唯一的)属性进行排序。例如按客户名称排序。目标是根据客户名称加载前 30 条记录,比如“ABC”,然后加载下一组。需要注意的是,Arango 中的数据是由多个用户同时编辑的,并且应用程序是实时的,所以当我去请求下一个“块”时,我原来的查询记录可能会发生变化。另一个问题是可能有超过 30 条“ABC”记录,所以我不能使用 FILTER doc.cName > @value,因为它可能会跳过一些“ABC”记录......有什么想法吗?
    • 如果您在唯一属性(例如_key)上添加另一个 FILTER 条件,则可以避免在有许多重复项时跳过记录:FILTER doc.cName > @value && doc._key > @lastKey。即使有许多记录与cName == "ABC"匹配,这也应该有效。
    • 进一步想一想,如果您按非唯一值排序,这会起作用吗?所以想象一下,按clientName排序,像你指出的那样过滤:FILTER doc.clientName > "@value" && doc._key > "@lastKey"。键不一定按客户端名称的顺序添加,所以此过滤器不会排除名称在字母数字上大于“@value”但其键不大于“@lastKey”的文档吗?
    • 想多了……我想你可以按clientName排序,然后按_key排序,然后使用上面提到的过滤器,它应该可以工作。
    • 退后一步:在初始搜索(LIMIT 0, x)发生后添加新记录时应该发生什么?他们是否应该出现在后续搜索中(使用 LIMIT y, x),如果,在哪里?用户是否希望他们的搜索和分页作为“快照”工作?如果是,那么可行的方法是在每个文档中包含一个时间戳(在插入时填充),并使用它在后续搜索中过滤掉较新的文档。这还可以防止“新”文档出现在搜索过程中,也不会在过滤条件下关注它们。
    【解决方案2】:

    如果您不应用 anny 排序过滤器,ArangoDB 不需要特殊序列。

    所以,做

    db._create("testCollection");
    for (var i = 0; i < 10; i ++) db.testCollection.save({which: i})
    db._query("FOR i IN testCollection RETURN i.which").toArray()
    

    会给你一个相当随机的序列。

    db._query("FOR i IN testCollection SORT i.which RETURN i.which").toArray()
    

    会给你一个格式良好的结果。

    然后你可以这样做:

    db._query("FOR i IN testCollection SORT i.which LIMIT 3, 5 RETURN i.which").toArray()
    

    使用限制。

    不过,您也可以将use cursors 转为fetch partial results

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多