Can't delete/remove multiple property keys on Vertex Titan 1.0 Tinkerpop 3
Asked Answered
H

2

7

Very basic question,
I just upgraded my Titan from 0.54 to Titan 1.0 Hadoop 1 / TP3 version 3.01.

I encounter a problem with deleting values of

Property key: Cardinality.LIST/SET

Maybe it is due to upgrade process or just my TP3 misunderstanding.

 // ----- CODE ------:

tg = TitanFactory.open(c);

TitanManagement mg = tg.openManagement();

//create KEY (Cardinality.LIST) and commit changes
tm.makePropertyKey("myList").dataType(String.class).cardinality( Cardinality.LIST).make();
mg.commit();

//add vertex with multi properties

Vertex v = tg.addVertex();

v.property("myList", "role1");
v.property("myList", "role2");
v.property("myList", "role3");
v.property("myList", "role4");
v.property("myList", "role4");

Now, I want to delete all the values "role1,role2...."

// iterate over all values and try to remove the values 
 List<String> values = IteratorUtils.toList(v.values("myList"));
        for (String val : values) {
            v.property("myList", val).remove();
         }
  tg.tx().commit();

//---------------- THE EXPECTED RESULT ----------: Empty vertex properties

But unfortunately the result isn't empty:

System.out.println("Values After Delete" + IteratorUtils.toList(v.values("myList")));

//------------------- OUTPUT --------------:

After a delete, values are still apparent!

15:19:59,780  INFO ThriftKeyspaceImpl:745 - Detected partitioner org.apache.cassandra.dht.Murmur3Partitioner for keyspace titan

15:19:59,784  INFO Values After Delete [role1, role2, role3, role4, role4]

Any ideas?

Hanako answered 11/4, 2016 at 13:7 Comment(1)
Although a Titan related question with a neo4j tag, the reader should be advised that the proposed answer works with Neo4jInamorata
U
2

property(key, value) will set the value of the property on the vertex (javadoc). What you should do is get the VertexProperties (javadoc).

for (VertexProperty vp : v.properties("name")) {
    vp.remove();
}

@jbmusso offered a solid solution using the GraphTraversal instead.

Unsearchable answered 11/4, 2016 at 14:55 Comment(5)
Thanks both solutions works , but because my titan upgrade i have a lot of legacy code that similar to TP2 , now i don't know if it better to replace all code with "traversal" instead of basic queries like: "tg.query().has(NODE_TYPE, NodeType.USER.name()).vertices() ....,etc'" I'm a little confuse what is better for performance ?? and when i need to use the "traversal" features...thanks a lotHanako
Favor maintainability and expressiveness of your queries over performance, and use traversals as much as you can. Traversals also have built-in optimization strategies that can kick in for free and I don't think you should worry about the traversal overhead, if any.Inamorata
I agree with @Inamorata plus I would also suggest that you migrate over to the TinkerPop 3 traversal APIs (rather than Titan query()) because it would give you more flexibility should you ever decide to choose a different graph backend.Unsearchable
Thanks for the answers , but i dont understand what exactly the "tg.traversal()" do and how often i need to execute it ? , Does it keep live refferences to all the graph nodes (vertexes,edges) ? Or each time when i need to interact with db ( retrieve data or update new node) make again the tg.traversal() call ..., it seems that this call traverse all the graph again and again...Maybe i need traverse only once at the init call of the server, and during the running use that reference to init traversal()..? BR :)Hanako
You should create the traversal object once and reuse it -- TitanGraph graph = TitanFactory.open('conf/titan.properties'); GraphTraversalSource g = graph.traversal(); -- read more about it in the TinkerPop docs tinkerpop.apache.org/docs/3.0.2-incubating/#_the_graph_processUnsearchable
I
11

You're not executing graph traversals with the higher level Gremlin API, but you're currently mutating the graph with the lower level graph API. Doing for loops in Gremlin is often an antipattern.

According to the TinkerPop 3.0.1 Drop Step documentation, you should be able to do the following from the Gremlin console:

v = g.addV().next()
g.V(v).property("myList", "role1")
g.V(v).property("myList", "role2")
// ...
g.V(v).properties('myList').drop()
Inamorata answered 11/4, 2016 at 14:8 Comment(1)
Something to note from the JavaDoc about dropping a key: "Removes elements and properties from the graph. This step is not a terminating, in the sense that it does not automatically iterate the traversal. It is therefore necessary to do some form of iteration for the removal to actually take place. In most cases, iteration is best accomplished with g.V().drop().iterate()." See hereDemigod
U
2

property(key, value) will set the value of the property on the vertex (javadoc). What you should do is get the VertexProperties (javadoc).

for (VertexProperty vp : v.properties("name")) {
    vp.remove();
}

@jbmusso offered a solid solution using the GraphTraversal instead.

Unsearchable answered 11/4, 2016 at 14:55 Comment(5)
Thanks both solutions works , but because my titan upgrade i have a lot of legacy code that similar to TP2 , now i don't know if it better to replace all code with "traversal" instead of basic queries like: "tg.query().has(NODE_TYPE, NodeType.USER.name()).vertices() ....,etc'" I'm a little confuse what is better for performance ?? and when i need to use the "traversal" features...thanks a lotHanako
Favor maintainability and expressiveness of your queries over performance, and use traversals as much as you can. Traversals also have built-in optimization strategies that can kick in for free and I don't think you should worry about the traversal overhead, if any.Inamorata
I agree with @Inamorata plus I would also suggest that you migrate over to the TinkerPop 3 traversal APIs (rather than Titan query()) because it would give you more flexibility should you ever decide to choose a different graph backend.Unsearchable
Thanks for the answers , but i dont understand what exactly the "tg.traversal()" do and how often i need to execute it ? , Does it keep live refferences to all the graph nodes (vertexes,edges) ? Or each time when i need to interact with db ( retrieve data or update new node) make again the tg.traversal() call ..., it seems that this call traverse all the graph again and again...Maybe i need traverse only once at the init call of the server, and during the running use that reference to init traversal()..? BR :)Hanako
You should create the traversal object once and reuse it -- TitanGraph graph = TitanFactory.open('conf/titan.properties'); GraphTraversalSource g = graph.traversal(); -- read more about it in the TinkerPop docs tinkerpop.apache.org/docs/3.0.2-incubating/#_the_graph_processUnsearchable

© 2022 - 2024 — McMap. All rights reserved.