Efficient way to replace SET/LIST property in Janusgraph

2.4k views Asked by At

In JanusGraph, I want to replace entire value of SET(or LIST) property. Accoding to this article, both storage backend and index backend (ES, Solr) behavior MUST be taken into account for consistency and efficiency though, the article was written about Titan 1.0.

Currently, I have two option to do it as follows. Which one is better ? Or is there best way to update SET/LIST property in JanusGraph.

  • JanusGraph version: github master
  • Gremlin version: 3.2.6

Sample schema

mgmt = graph.openManagement()
person = mgmt.makeVertexLabel('Person').make()
name = mgmt.makePropertyKey('name').dataType(String.class).cardinality(SET).make()
mgmt.buildIndex('i_person_name', Vertex.class).addKey(name, Mapping.STRING.asParameter()).buildMixedIndex('elastic-search')
mgmt.commit()

person = g.addV('Person').property('name', 'Alexander').property('name', 'Alex').next()
g.tx().commit()

Solution 1

Drop entire property values, and then set new values.

new_names = ['Alex', 'Alexander Emmanuel Rodriguez'] as Set

v = g.V().hasLabel('Person').has('name', 'Alexander').next()
g.V(v).properties('name').drop().iterate()
new_names.each{
    v.property('name', it)
}

g.tx().commit()

Solution 2

Drop only old values and set only new values.

new_names = ['Alex', 'Alexander Emmanuel Rodriguez'] as Set

v = g.V().hasLabel('Person').has('name', 'Alexander').next()
v.properties('name').each {
    new_names.remove(it.value()) ? null : it.remove()
}
new_names.each {
    v.property('name', it)
}

g.tx().commit()
1

There are 1 answers

2
Daniel Kuppitz On BEST ANSWER

You can drop old and add new values in a single traversal. I have to admit it's not the easiest traversal, but it works:

gremlin> g = TinkerGraph.open().traversal()
==>graphtraversalsource[tinkergraph[vertices:0 edges:0], standard]
gremlin> g.addV("person").property(list, "name", "Alexander")
==>v[0]
gremlin> g.V().valueMap()
==>[name:[Alexander]]

gremlin> new_names = [ "Alex"
                     , "Alexander Emmanuel Rodriguez"] as Set
==>Alex
==>Alexander Emmanuel Rodriguez

gremlin> g.withSideEffect("nn", new_names).
           V().has("person","name","Alexander").as("p").
           sideEffect(
             properties("name").choose(value().where(without("nn")),
                                         drop(), value().store("x"))).barrier().
           select("nn").unfold().where(without("x")).as("n").
           select("p").property(list, "name", select("n")).iterate()

gremlin> g.V().valueMap()
==>[name:[Alex,Alexander Emmanuel Rodriguez]]