0

Why does batch.set_labels() work with batch.create() but not with batch.get_or_create_indexed_node()

This works, a node is created as expected.

batch = neo4j.WriteBatch(neo4j_graph)
a = batch.create(node({'name': 'a'}))
batch.set_labels(a, 'Person')
batch.submit()

This does not work, no node is created.

graph_db.get_or_create_index(neo4j.Node, 'node_index')
batch = neo4j.WriteBatch(neo4j_graph)
b = batch.get_or_create_indexed_node(NEO4J_NODE_INDEX, 'name',
    'b',
    {'name': 'b'}
)
batch.set_labels(b, 'Person')
batch.submit()
Cathal Coffey
  • 1,105
  • 2
  • 20
  • 35

1 Answers1

0

This is a limitation of the way that the batch endpoint and other resources work through the REST interface and requires some familiarity with the REST API to fully understand.

The batch endpoint bundles up a number of HTTP requests into a single call that is carried out within a single transaction. One of the values returned from such requests is a location URI and this can in some cases be passed through into other requests. For example, one may want to create two nodes and then a relationship connecting them. This can be achieved by using pointers such as {0} and {1} to refer to the nodes previously created as the endpoints of the new relationship. For more details on this notation, see here.

The difficulty comes when using the legacy index calls. When a node is created through a legacy index, the location URI returned is that of the index entry point, not of the newly-created node. This cannot be used as a reference (such as in your set_labels call above) and so the expected behaviour does not occur.

Unfortunately, there is no straightforward workaround for this. You can move over to Cypher but you have no way to write to legacy indexes there. Perhaps you can look at schema indexes for this instead?

Nigel Small
  • 4,475
  • 1
  • 17
  • 15