Понимание различных методов добавления ребер с помощью Gremlin-Python
Я пытаюсь понять различия в методах и лучший синтаксис для добавления ребер (между существующими вершинами) в Gremlin-Python.
Прочитав несколько постов здесь на SO, я разделил несколько разных подходов, которые я нашел, на несколько вопросов.
Большое спасибо за любые отзывы заранее!
1) Каков наилучший порядок добавления свойств к краю при его создании: какой из них будет лучшим вариантом (если вообще есть какое-либо существенное различие)?
g.V().property("prop1", "prop1_val").as_("a")
.V().property("prop2", "prop2_val").as_("b")
.addE("some_relationship")
# rest of traversal option 1:
.property("prop1_val_weight", 0.1d)
.from_("a").to("b")
# rest of traversal option 2:
.from_("a").to("b")
.property("prop1_val_weight", 0.1d)
2) Какова цель и правильное использование "__. V ()"?
g.V().property("prop1", "prop1_val")
.as_("a").V().property("prop2", "prop2_val")
.as_("b").addE("some_relationship")
.property("prop1_val_weight", 0.1d)
# AND THEN:
.from_("a").to("b")
# VERSUS:
.from_(__.V("a")).to(__.V("b"))
3) В чем различия между использованием "свойства" и "свойства":
g.V().property("prop1", "prop1_val").as_("a")
# VERSUS:
g.V().properties("prop1", "prop1_val").as_("a")
# REST OF THE TRAVERSAL:
.V().property("prop2", "prop2_val").as_("b")
.addE("some_relationship")
.property("prop1_val_weight", 0.1d)
.from_("a").to("b")
4) Что происходит, когда не указана вершина / вершины ".to ()", и в этом случае также используется "__. V ()":
g.V().property("prop1", "prop1_val").as_("a")
.V().property("prop2", "prop2_val").as_("b")
.addE("some_relationship").to(__.V()
.has("prop2", "prop2_val"))
5) Каковы причины добавления ".profile ()" в конце обхода:
g.V('Alice').as_('v').V('Bob').coalesce(inE('spokeWith')
.where(outV().as_('v')).addE('spokeWith')
.property('date', 'xyz').from_('v'))
.profile()
6) Каково правильное использование и вообще дополнительное преимущество использования шага "coalesce" при добавлении ребер, как если бы он использовался при обходе в 5 ^^?
7) И несколько общих вопросов:
- в чем преимущество поиска метки, например, "gV().has("LABEL1", "prop1", "prop1_val").as_("a") [etc.]"
- после назначения обхода переменной (например, " t = gV() ... " в несколько этапов, достаточно ли затем один раз, в конце, вызвать "t.iterate ()" или это нужно делать каждый раз время?
- в какой момент в скрипте должен вызываться tx.commit(): достаточно ли его вызова только один раз, в конце нескольких обходов?
1 ответ
1) Каков наилучший порядок добавления свойств к краю при его создании?
Я не думаю, что есть "лучший порядок", говоря лично, но лично я думаю, что лучше читать from()
а также to()
немедленно следовать addE()
,
2) Какова цель и правильное использование " __.V() "?
Вы не можете использовать середину обхода V()
таким образом. Делая это, в основном говорят "найди мне вершину в графе с T.id
"а", который не существует. "a" в вашем случае - это метка шага, которая относится только к области этого обхода.
3) В чем различия между использованием "свойства" и "свойства":
Существует огромная разница. property(k,v)
является шагом мутации, который изменяет элемент графа в потоке путем добавления / обновления ключа свойства с указанным значением. properties(k...)
получает список свойств, указанных предоставленными ключами (то есть операция чтения).
4) Что происходит, когда не указана вершина / вершины ".to()", и в этом случае также используется "__. V ()"
Почему бы не запустить Gremlin Console и посмотреть:
gremlin> g.addV().addE('self')
==>e[17][16-self->16]
gremlin> g.addV().as('z').addE('self').property('x','y').from('z').to(V().has('person','name','nobody'))
The provided traverser does not map to a value: v[20]->[TinkerGraphStep(vertex,[~label.eq(person), name.eq(nobody)])]
Type ':help' or ':h' for help.
Display stack trace? [yN]
5) Каковы причины добавления " .profile()" в конце обхода:
Те же причины, по которым вы бы профилировали свой код или объясняли SQL-запрос - чтобы получить более подробное понимание того, что делает этот код. Может быть, вам нужно посмотреть, правильно ли используется индекс, или выяснить, какой шаг выполняется дольше всего, чтобы узнать, сможете ли вы лучше оптимизировать свой обход.
6) Каково правильное использование и вообще дополнительное преимущество использования шага "coalesce" при добавлении ребер, как если бы он использовался при обходе в 5 ^^?
Если я не читаю это, я не вижу никакой причины использовать coalesce()
как это используется в 5, поскольку нет второго аргумента для этого. Вы обычно используете coalesce()
в контексте добавления вершин / ребер, когда вы хотите "получить или создать" или "вставить" элемент - вы можете узнать больше об этом здесь.
в чем преимущество поиска метки, например, "gV().has("LABEL1", "prop1", "prop1_val").as_("a") [etc.]"
Лучше всего включать метку вершины при выполнении has()
так как вы затем явно именуете пространство, по которому вы ищете. Вы использовали "prop1" в своем примере - если "prop1" не был глобально уникальным ключом и вы хотели только вершины "LABEL1", но вершины "LABEL2" также имели значения "prop1", то вы, возможно, не получаете то, что хотите. Я предполагаю, что если вы используете глобально уникальные имена ключей, то это не проблема, но я думаю, что если вы хотите максимизировать переносимость вашего Gremlin, вы, возможно, захотите заняться практикой, так как я думаю, что есть некоторые графические системы, которые требовать уточнения этикетки.
после назначения обхода переменной (например, " t = gV() ... " в несколько этапов, достаточно ли затем один раз, в конце, вызвать "t.iterate()" или это нужно делать каждый раз время?
iterate()
это завершающий шаг. Вы обычно вызываете его для генерации любых побочных эффектов, которые могут возникнуть при обходе. После "итерации" вы действительно не сможете вызывать его снова, поскольку это не будет иметь никакого эффекта, поскольку итерация является односторонней операцией, а после исчерпания объектов-обходчиков ничего не остается iterate()
очередной раз.
в какой момент в скрипте должен вызываться tx.commit(): достаточно ли его вызова только один раз, в конце нескольких обходов?
Если вы следуете передовой практике, вы не звоните commit()
вообще. Gremlin Server управляет вашими транзакциями за вас. Один запрос (то есть обход) - это в основном одна транзакция. Единственный раз, когда вам нужно позвонить commit()
если вы сами решаете управлять транзакциями в контексте сеанса или сценария действительно длительного запуска. Если вы создаете новое приложение, вам следует избегать любой из этих опций и просто использовать обходы на основе байт-кода.