Is it possible to change edges between vertices in gremlin - gremlin

I have a scenario where I may need to update the from/to vertex of an already existing edge. I dont think there is any mechanism in gremlin to do so. So, what would be an ideal approach to achieve such functionality? What I can think of is -
Assuming To Vertex changes over time in an edge, Make sure the Edge ID is unique something like "From-Relationshipname"
While adding new edges check if Edge is already present then drop old Edge using the EdgeId and create a new one
Is it an efficient way?

Check the following recipe published in Gremlin docs for moving an edge.
The "marko" vertex contains a "knows" edge to the "vadas" vertex. The following code shows how to "move" that edge to the "peter" vertex in a single traversal:
g.V().has('name','marko').as('a').
outE('knows').as('e1').filter(inV().has('name','vadas')).
V().has('name','peter').
addE('knows').from('a').as('e2').
sideEffect(select('e1').properties().
unfold().as('p').
select('e2').
property(select('p').key(), select('p').value())).
select('e1').drop()
Source: https://tinkerpop.apache.org/docs/current/recipes/#edge-move

Related

Is there a version of gremlin "bothE" that isn't actually "eitherE"?

I want to find all vertecies which has an edge to a specific vertex but the vertex should also have an edge back to the other vertex.
The following query does not behave in the way i want, it seems that bothE() means either in or out or both, not explicitly that both an incoming and outgoing edge must be present.
g.V(id).bothE().outV()
I also don't want the starting vertex (g.v(id)) to be returned. I've looked through the documentation but there's so many complex queries available that it'll take me a very long time to find this one simple thing i need. Any help is appreciated
You need something like this
g.V(id).as('a').out().where(out().as('a'))
Which basically says, find everything I am connected to by an outgoing edge that also has an outgoing edge back to me.

Gremlin query to find the entire sub-graph that a specific node is connected in any way to

I am brand new to Gremlin and am using gremlin-python to traverse my graph. The graph is made up of many clusters or sub-graphs which are intra-connected, and not inter-connected with any other cluster in the graph.
A simple example of this is a graph with 5 nodes and 3 edges:
Customer_1 is connected to CreditCard_A with 1_HasCreditCard_A edge
Customer_2 is connected to CreditCard_B with 2_HasCreditCard_B edge
Customer_3 is connected to CreditCard_A with 3_HasCreditCard_A edge
I want a query that will return a sub-graph object of all nodes and edges connected (in or out) to the queried node. I can then store this sub-graph as a variable and then run different traversals on it to calculate different things.
This query would need to be recursive as these clusters could be made up of nodes which are many (inward or outward) hops away from each other. There are also many different types of nodes and edges, and they all must be returned.
For example:
If I specified Customer_1 in the query, the resulting sub-graph would contain Customer_1, Customer_3, CreditCardA, 1_HasCreditCard_A, and 3_HasCreditCard_A.
If I specififed Customer_2, the returned sub-graph would consist of Customer_2, CreditCard_B, 2_HasCreditCard_B.
If I queried Customer_3, the exact same subgraph object as returned from the Customer_1 query would be returned.
I have used both Neo4J with Cypher and Dgraph with GraphQL and found this task quite easy in these two langauges, but am struggling a bit more with understanding gremlin.
EDIT:
From, this question, the selected answer should achieve what I want, but without specifying the edge type by changing .both('created') to just .both().
However, the loop syntax: .loop{true}{true} is invalid in Python of course. Is this loop function available in gremlin-python? I cannot find anything.
EDIT 2:
I have tried this and it seems to be working as expected, I think.
g.V(node_id).repeat(bothE().otherV().simplePath()).emit()
Is this a valid solution to what I am looking for? Is it also possible to include the queried node in this result?
Regarding the second edit, this looks like a valid solution that returns all the vertices connected to the starting vertex.
Some small fixes:
you can change the bothE().otherV() to both()
if you want to get also the starting vertex you need to move the emit step before the repeat
I would add a dedup step to remove all duplicate vertices (can be more than 1 path to a vertex)
g.V(node_id).emit().repeat(both().simplePath()).dedup()
exmaple: https://gremlify.com/jngpuy3dwg9

How to remove an edge between two vertices from DSE schema

We have an edge between two vertices in datastax graph.
How can I remove the edge from the schema itself?
I tried this:
schema.edgeLabel("belongswithin").connection("poi", "region").drop()
but there is no drop method to delete an edge like this.
I can't run:
schema.edgeLabel("belongswithin").drop()
as I am having the same edge being used between the other two vertices which I don't want to drop?
In DSE Graph, an EdgeLabel can be dropped, but not selectively for a particular connection between two VertexLabels. You don't say which version of DSE you are using, but I'm pretty certain you'll need to drop and rewrite the schema, then load your data again. If you are a DataStax customer, you might want to contact Support to see if there is any assistance they can provide.

ArangoDB anonymous graph traversal

I am planing to use ArangoDB and I am faced with a problem I don't know how to solve. I would like to do simple traversals but in my case but there are two requirements that I don't know how to solve:
I will not know in advance the type of vertices than an edge will connect to. I want to be able to connect edge of one type to any vertex on any side.
For one vertex, I want to retrieve all connected vertices (depth 1) no matter the edge type.
For the requirement 1, an example would be a Tag vertex (to tag some entity with some information) and I want to be able to tag any vertex using i.e. HasTag edge in a named graph. From what I currently see is that I need to define the "From" collections ("To" collection is the Tag collection) and this is limited to 10 collections. Since I could have 100 or more From collections I don't see how to solve this with named graphs.
Option would be to use anonymous graphs but then I have a problem in the second requirement. I also want to have an option, when given a vertex, to find all connected vertices (depth = 1) no matter the type of an edge. In an anonymous graph I would need to specify all of the edge collections in a query and again, there could be 100 or more of them. I don't know if there is a limit to this number but I would assume there is one - maybe I'm mistaken since I haven't yet tried it out.
Has anyone any idea how to solve this with ArrangoDB? I really like the database but I would like it to be more "typeless", that is, that I wouldn't have to define the type of vertex collection an edge can connect to.
Best regards
Tomaz
You can have more than 10 vertex collections in a named graph. The limitation of 10 only exists in the webUI. Creating the named graph over the ArangoShell or the server console will work.

What is wrong with light weight edges?

I created an edge without attribute and guess what? it was created but still can not query it but then i created the same edge again and now they both are having same rid>?
I suggest you to start using OrientDB from the tutorial. This is an extract:
Starting from OrientDB v1.4.x edges, by default, are managed as lightweight edges: they don't have own identities as record, but are physically stored as links inside vertices. OrientDB automatically uses Lightweight edges only when edges have no properties, otherwise regular edges are used. From the logic point of view, lightweight edges are edges at all the effects, so all the graph functions work correctly. This is to improve performance and reduce the space on disk. But as a consequence, since lightweight edges don't exist as separate records in the database, the following query will not return the lightweight edges:
SELECT FROM E
In most of the cases Edges are used from Vertices, so this doesn't cause any particular problem. In case you need to query Edges directly, even those with no properties, disable lightweight edge feature by executing this command once:
ALTER DATABASE CUSTOM useLightweightEdges=false
This will only take effect for new edges. For more information look at Troubleshooting.
You can query for a list of names of edges with:
select name from ( select expand(classes) from metadata:schema ) where superClass="E"

Resources