ArangoDB получает индекс документа

Есть ли способ получить индекс конкретного документа в ArangoDB, чтобы использовать его в операции LIMIT? Например, предположим, что я ищу документ по его идентификатору и обнаруживаю, что его индекс равен 534, тогда я бы использовал его так:

LIMIT 534, 30

... и верните следующие 30 документов после документа, который я просмотрел. Однако я не могу найти способ получить индекс документа с помощью AQL ...


person skinneejoe    schedule 19.11.2015    source источник


Ответы (2)


Вопрос в том, что на самом деле должны означать следующие документы.

Если следующий здесь означает порядок индексации ключей документа:

У документа нет определенного «порядка» или «индекса» внутри коллекции. Документы в коллекции упорядочены по их атрибуту _key / _id в несортированном первичном индексе.

Чтобы перейти к следующему ключу документа (предположим, что ключи отсортированы лексикографически), нужно прочитать все ключи коллекции, отсортировать их и каким-то образом найти индекс текущего документа, чтобы перейти к следующему ключу. Это было бы ужасно неэффективно.

Другие индексы в коллекции необязательны, поэтому нельзя полагаться на их наличие и возможность использования для такого запроса.

Если здесь следующий означает порядок вставки или обновления, то также нет разумного способа перейти к следующим документам.

Обходной путь может заключаться в использовании отсортированного (например, skiplist) индекса для некоторого атрибута документа, в идеале уникального, и заполнения его всякий раз, когда документ вставляется (и, возможно, обновляется, если обновления также должны изменить порядок документа).

Затем, чтобы найти следующие документы, сделайте следующее:

  • сначала найдите нужный документ по его _id или _key и загрузите данные документа в приложение

  • получить атрибут документа, на котором есть отсортированный индекс, и использовать его в последующем запросе AQL следующим образом

Это позволит вам найти документы, следующие за исходным, однако вы должны каким-то образом сохранить атрибут порядка:

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

Это будет легко сделать, если в ваших документах есть какой-то атрибут, который в любом случае можно использовать для заказа, но будет неуклюжим решением, если у них нет такого атрибута.

person stj    schedule 20.11.2015
comment
Проблема в том, что я сортирую по разным, не всегда уникальным атрибутам. Например, сортировка по имени клиента. Цель состоит в том, чтобы загрузить первые 30 записей на основе имени клиента, скажем, ABC, а затем загрузить следующий набор. Предостережение: данные в Arango редактируются сразу несколькими пользователями, и приложение работает в режиме реального времени, поэтому мои исходные запрошенные записи могут измениться к тому времени, когда я пойду запросить свой следующий «кусок». Другая проблема в том, что может быть более 30 записей ABC, поэтому я не могу использовать FILTER doc.cName ›@value, потому что он может пропустить некоторые записи ABC ... Есть мысли? - person skinneejoe; 20.11.2015
comment
Вы можете избежать пропуска записей при большом количестве дубликатов, если вы добавите другое условие ФИЛЬТРА для уникального атрибута (например, _key): FILTER doc.cName > @value && doc._key > @lastKey. Это должно работать, даже если есть много записей, совпадающих с cName == "ABC. - person stj; 23.11.2015
comment
Если подумать об этом дальше, будет ли это работать, если вы выполняете сортировку по неуникальному значению? Итак, представьте, сортировка по clientName, фильтрация, как вы указываете: FILTER doc.clientName ›@value && doc._key› @lastKey. Ключи не обязательно добавляются в порядке имен клиентов, поэтому не будет ли этот фильтр исключать документ, имя которого буквенно-цифровое больше, чем @value, но чей ключ не больше, чем @lastKey? - person skinneejoe; 23.11.2015
comment
Подумав об этом подробнее ... Я полагаю, вы могли бы отсортировать по clientName, затем отсортировать по _key, затем использовать фильтр, как указано выше, и он должен работать. - person skinneejoe; 23.11.2015
comment
Вернемся на шаг назад: что должно произойти, если новые записи будут добавлены после первоначального поиска (с LIMIT 0, x)? Должны ли они появляться при последующих поисках (с LIMIT y, x), и если, где? Ожидают ли пользователи, что их поиск и разбивка на страницы будут работать как снимки? Если да, то что может сработать, так это включить метку времени в каждый документ (заполняется при вставке) и использовать ее для фильтрации новых документов при последующих поисках. Это также предотвратит появление новых документов в процессе поиска и не позволит им заботиться о них в условиях фильтрации. - person stj; 24.11.2015
comment
Что ж, это сложно ... поскольку приложение работает в реальном времени, записи могут перемещаться в зависимости от того, когда они были изменены. Таким образом, в идеале он должен выяснить, какая последняя запись загружена с сервера, убедиться, что она не обновлялась, перемещаясь, таким образом, в верхнюю часть списка, а затем запросить любые записи, следующие за ней. Честно говоря, сейчас я перешел на диапазон дат с разбивкой на страницы из-за сложности. Но я вернусь к этому в конце концов, когда у меня будет больше времени ... - person skinneejoe; 25.11.2015
comment
Вы знаете, когда я набирал свой последний комментарий, меня поразило, что, возможно, диапазон дат - это самый простой способ сделать это ... Меня действительно не волнует получение твердых 30 записей каждый раз. Я мог бы просто запросить у сервера записи между двумя диапазонами дат. Затем каждый раз, когда запускается следующая загрузка, просто перемещайте диапазон дат дальше. Полагаю, это не идеальное решение, но, вероятно, этого хватит. Я приветствую комментарии о том, как заставить это работать по-другому. Спасибо! - person skinneejoe; 25.11.2015

Если вы не применяете какой-либо фильтр сортировки, 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()

работать с ограничениями.

Однако вы также можете использовать курсоры для получить частичные результаты.

person dothebart    schedule 20.11.2015