Когда вы пишете Gremlin, вам нужно думать о потоках. V()
создает поток всех вершин в графе. Представьте, что каждый элемент в этом потоке, попадающий в фильтры hasLabel()
и has()
, должен быть спарен до тех пор, пока они не достигнут шага сокращения fold()
, в результате которого получается List
с вершинами, которые соответствуют критериям фильтра, или, если их нет, он simple создает пустой список, который становится новым объектом в потоке.
Оттуда coalesce()
создает случай типа if-then, когда первый предоставленный ему дочерний поток, возвращающий значение, заканчивается, а остальные дочерние потоки игнорируются. Следовательно, если unfold()
, который принимает List
с вершинами, созданными fold()
, содержит вершину, то он передается потоку, и эта вершина существует, и, таким образом, coalesce()
создает эту существующую вершину и переходит к последним двум шаги property("value", "A").property("action", "update")
. Если List
пуст, то поток unfold()
не создает объектов и переходит к следующему дочернему потоку, который начинается с addV()
. Поток addV()
, очевидно, создаст новый Vertex
с указанными свойствами, но затем coalesce()
в качестве его родителя создаст эту вновь добавленную вершину в потоке, и он также перейдет к этим двум последним шагам и перезапишет свойство значения, которые вы указали для addV()
.
Если вы хотите иметь два отдельных пути, то вы можете сделать что-то вроде этого:
g.V().hasLabel("Entity").has("identifier", "123").fold()
.coalesce((Traversal)
__.unfold()
.property("value", "A")
.property("action", "update"),
__.addV("Entity")
.property("identifier", "123")
.property("value", "A")
.property("action", "add")
)
.iterate();