Как выполнить пагинацию в Gremlin

В Tinkerpop 3 как выполнить разбиение на страницы? Я хочу получить первые 10 элементов запроса, а затем следующие 10, не загружая их все в память. Например, приведенный ниже запрос возвращает 1000000 записей. Я хочу получить их 10 на 10, не загружая сразу все 1000000.

g.V().has("key", value).limit(10)

Редактировать

Решение, которое работает через HttpChannelizer на сервере Gremlin, было бы идеальным.


person Mohamed Taher Alrefaie    schedule 03.10.2016    source источник


Ответы (2)


С функциональной точки зрения, неплохо выглядит Gremlin для разбиения по страницам:

gremlin> g.V().hasLabel('person').fold().as('persons','count').
               select('persons','count').
                 by(range(local, 0, 2)).
                 by(count(local))
==>[persons:[v[1],v[2]],count:4]
gremlin> g.V().hasLabel('person').fold().as('persons','count').
               select('persons','count').
                 by(range(local, 2, 4)).
                 by(count(local))
==>[persons:[v[4],v[6]],count:4]

Таким образом вы получите общее количество вершин с результатом. К сожалению, fold() заставляет вас подсчитывать все вершины, что потребует повторения их всех (т.е. занесения их всех в память).

В этом случае действительно невозможно избежать итерации всех 100 000 вершин, если вы намереваетесь выполнить обход за несколько отдельных попыток. Например:

gremlin> g.V().hasLabel('person').range(0,2)
==>v[1]
==>v[2]
gremlin> g.V().hasLabel('person').range(2,4)
==>v[4]
==>v[6]

Первый оператор такой же, как если бы вы завершили обход с помощью limit(2). Во втором обходе, которому нужны только вторые две вершины, это не значит, что вы волшебным образом пропускаете итерацию первых двух, поскольку это новый обход. Я не знаю ни одной реализации графической базы данных TinkerPop, которая бы делала это эффективно - все они имеют такое поведение.

Единственный способ сделать десять вершин за раз, не имея их всех в памяти, - это использовать тот же экземпляр Traversal, что и в:

gremlin> t = g.V().hasLabel('person');[]
gremlin> t.next(2)
==>v[1]
==>v[2]
gremlin> t.next(2)
==>v[4]
==>v[6]

В этой модели вы выполняете итерацию вершин только один раз и не помещаете их все в память в один момент времени.

Некоторые другие мысли по этой теме можно найти в этом сообщение в блоге.

person stephen mallette    schedule 03.10.2016
comment
Спасибо, Стивен, последнее решение звучит хорошо. Однако как бы вы это сделали, если используете HttpChannelizer? - person Mohamed Taher Alrefaie; 03.10.2016
comment
Если вы используете HTTP, вы не можете. Вам придется переключиться на веб-сокеты, и тогда вы получите эту потоковую передачу бесплатно, или, если вы хотите контролировать ее больше вручную, вы можете использовать сеанс. - person stephen mallette; 03.10.2016
comment
Возможно ли в python сохранить обход для последующих нескольких итераций на .next() шаг? В java (как я понимаю для janus-graph) это можно сделать с помощью сеанса для запросов, чтобы - создать сеанс Client client = cluster.connect("uniqueSessionName",true);, определить переменную обхода одним запросом (например, t = g.V().hasLabel('person');) и перебрать этот обход в другом запросе (например, t.next(2)) Но как это можно сделать для питонгремля? - person palandlom; 07.12.2018
comment
в python нет опции connect(), но вы можете создать сообщение запроса сеанса самостоятельно и отправить его через Client.submit(). формат этого сообщения - здесь и не Это так не отличается от стандартной бессеансовой формы сообщения, созданного в submit(), показанном здесь - person stephen mallette; 07.12.2018
comment
Спасибо, Стивен. Но когда я пытаюсь установить processor = session в `message = request.RequestMessage (processor = 'session', op = 'eval' ... 'session': '4ad866cd-def9-4a76-86a1-f788785bb482', ' aliases ': {' g ': self._traversal_source}}) `... Я получаю ошибку Exception("Unknown processor") - насколько я понимаю, такого процессора нет в serializer.py - person palandlom; 07.12.2018
comment
хм - извините, я не знал об этом. я думаю, вам нужно добавить процессор к сериализатору ?? Я полагаю, что gremlin-python должен быть изменен для поддержки этого изначально. честно говоря, было бы лучше постараться избегать сеансов, если можете. они не поддерживаются полностью на всех графиках, поэтому ваш код становится менее переносимым для их использования. они также сопряжены с небольшими накладными расходами. - person stephen mallette; 07.12.2018

Почему бы не добавить order().by() и не выполнить range() функцию в запросе gremlin.

person jaypeeig    schedule 13.02.2020