How to delete vertex on AgensGraph? - vertex

I want to delete vertex on AgensGraph.
agens=# create (:v1{id:1})-[:e1{id:2}]->(:v1{id:3});
GRAPH WRITE (INSERT VERTEX 2, INSERT EDGE 1)
agens=# match (n:v1{id:1}) delete n;
ERROR: vertices with edges can not be removed
But, there is an error on it.
How to delete vertex on AgensGraph?

Use DETACH before DELETE.
agens=# match (n:v1{id:1}) detach delete n;
GRAPH WRITE (DELETE VERTEX 1, DELETE EDGE 1)

Related

Unpack vertices' properties returned from a select()

I would like to write a MATCH query in gremlin to find a subgraph matching a particular pattern. The pattern of interest contains 4 different types/labels of nodes: c, p, r, and s. And 4 different types of edges as shown below:
(c)->[affecting]->(p)
(c)-[c_found_in_release]->(r)
(p)-[p_found_in_release]->(r)
(s)-[severity]->(c)
So far I have the query below which works fine, however, the results do not show the properties of the vertices returned. Since the verticies returned from the select() statement belong to different types of nodes, I cannot use something like value() or valueMap()
g.V().match(
__.as('c').out('affecting').as('p'), \
__.as('c').out('cve_found_in_release').as('r'), \
__.as('p').out('pack_found_in_release').as('r'), \
__.as('s').both('severity').as('c') \
). \
select('c', 'p', 'r', 's').limit(10)
Current result:
==>[c:v[0],p:v[3],r:v[6],s:v[10]]
How to get something more detailed like this instead:
Desired result:
==>[
c:[cve_id:[CVE-2021-3618],publishedOn:[2022-03-23],
p:[name:[vsftpd],version:[3.0.3]],
r:[sourceBranch:[1.0],detectedOn:[2022-04-05],status:[Upgraded]],
s:[severity:[High]],
]
You can simply add additional by() modulators. On the Tinkergraph modern example graph:
g = TinkerFactory.createModern().traversal()
g.V().match(
__.as('v').hasLabel('software').as('s'),
__.as('s').both().hasLabel('person').as('p')
).select('s', 'p')
.by(values('name', 'lang').fold())
.by(values('name', 'age').fold())
==>[s:[lop,java],p:[marko,29]]
==>[s:[lop,java],p:[josh,32]]
==>[s:[lop,java],p:[peter,35]]
==>[s:[ripple,java],p:[josh,32]]

Gremlin continue traversal only if 2 vertices are not the same

I have a query which looks at 2 different vertices and I want to stop traversing if they don't both roll up to the same root ancestor via a path of "contains" edges.
g.V('node1')
.until(hasLabel('root')).repeat(in('contains')).as('node1Root')
.V('node2')
.until(hasLabel('root')).repeat(in('contains')).as('node2Root')
//FILTER|WHERE clause
I'd like to confirm that node1Root and node2root are the same vertex before continuing the traversal, but for the life of me I cannot figure out how to do this.
I've tried the following:
g.V('node1')
.until(hasLabel('root')).repeat(in('contains')).as('node1Root')
.V('node2')
.until(hasLabel('root')).repeat(in('contains')).as('node2Root')
//.where('node1Root', P.eq('node2Root')
//.where(select("node1Root").is(P.eq("node2Root")))
//.where(select("node1Root").is("node2Root"))
What's interesting is that the following query does work to filter appropriately.
g.V('node1').as('1')
.V('node2').as('2')
.where('1', P.eq('2'))
I'm not sure if there's something up with the until/repeat that screws it up or if I'm just doing something blatantly wrong. Any help would be much appreciated.
Thanks!
I found How to check equality with nodes from an earlier part of query in Gremlin?
and it seems like you use "as" with the same key as the previous "as" and if they match its considered equal.
So here's the winner (I think):
g.V('node1')
.until(hasLabel('root')).repeat(in('contains')).as('node1Root')
.V('node2')
.until(hasLabel('root')).repeat(in('contains')).as('node2Root')
.where(select('node1Root').as('node2Root')
//.not(select('node1Root').as('node2Root')) //OR this to determine they aren't the same
//continue traversal
I also found that my original issue was that the .until().repeat() steps could return a LIST, but in my case I know that my graph model will always return a single 'root' so to make it work, I can use 'unfold'
g.V('node1')
.until(hasLabel('root')).repeat(in('contains')).unfold().as('node1Root')
.V('node2')
.until(hasLabel('root')).repeat(in('contains')).unfold().as('node2Root')
.where('node1Root', P.eq('node2Root')
I think I'll be going with the second solution because I'm much more confident in it, unless I hear otherwise.
You can try this gremlin query
g.V(node1-id)
.map(until(hasLabel('root')).repeat(in().aggregate('x')).cap('x')).as("array")
.V(node2-id)
.until(
as("i").select("array").unfold().as("j")
.where("i", eq("j"))
).repeat(in())
Here we are putting all the vertices in path to root from node1 in an array, and secondly we are checking existence of node in array.
this query can only work with traversal with only one iteration because aggregate step collect to a global variable to traversal that means it will be same array for every iteration. To fix this If you are doing this on jvm do use lamda/groovy closures
g.V(node-start-id-1,node-start-id-2)
.map(
{ x->
var v = x.get()
var g = getGraph().get().traversal();
g.V(v.id())until(hasLabel('root')).repeat(in().aggregate('x')).cap('x')).next()
}
)
.as("array")
.V(node2-id)
.until(
as("i").select("array").unfold().as("j")
.where("i", eq("j"))
).repeat(in())

How to set a Lisp list as the value of a JavaScript variable using parenscript?

I have:
(ps:ps (ps:var vertices (ps:lisp (cons 'list *VERTICES*))))
which evaluates to:
"var vertices = [0.0, -200.0, 0, ... 0.4, 40];"
which is the correct expected result.
Where:
ps refers to parenscript (full documentation is here).
*VERTICES* is just a plain flat list of
numbers in my global Lisp environment
However, When *VERTICES* is large, the evaluation leads to the error:
Error: Too many arguments.
While executing: PARENSCRIPT::COMPILE-SPECIAL-FORM, in process listener(1).
How do I get around this error?
Not knowing how parenscript really works internally, this problem is hard to solve. So I tried changing the way the list is passed to ps.
Here are a few failed attempts:
(ps:ps (ps:var vertices (ps:lisp (list *VERTICES*))))
=> "var vertices = 1(2, 3, 4, 0, 9, 0.1)();"
(ps:ps (ps:var vertices (ps:lisp *VERTICES*)))
=> "var vertices = 1(2, 3, 4, 0, 9, 0.1);"
(ps:ps (ps:var vertices *VERTICES*))
=> "var vertices = VERTICES;"
None are the correct expected output.
What is the right way to pass a Lisp list variable's value to parenscript to form a correct javascript array-variable assignment-statement?
I was able to reproduce this with 1000000 items. It seems that the parenscript compiler (which is sitting behind that ps macro) translates your list to a form (array 1 2 3 4 5 …) first. This means that array gets a million arguments, which is rather unusual for source code.
I'd recommend thinking over your design. Why do you want to create such a large vector in your source code? Should this maybe sit in a separate file, or be loaded at runtime over the network?
By the way, you can inspect what is happening by using the debugger you get thrown into at error. For example, in SLIME, I pressed v on the frame of compile-special-form to see the corresponding source code of parenscript. This showed the following expression:
(apply expression-impl (cdr form))
which suggests that expressions will be subject to call-arguments-limit.

How to create sub class of superclass V in graph using gremlin console

I tried stackoverflow, gremlin docs. But couldn't find the solution.
I tried:
g.v('class:Employee',[EmpId:'398']);
It created one vertex. But again I tried with different value. I couldn't insert new vertex.
gremlin> g.addVertex('Class:Employee',[EmpId:'589'])
groovysh_parse: 51: expecting '(', found 'g' # line 51, column 1.
g.addVertex('Class:Employee',[EmpId:'589'])
That error usually means that the input buffer is messed up because you had a syntax error from the previous line. In this case it looks like the buffer is expecting an open parenthesis, but you've instead started a new command. These issue can be fixed with a call to clear:
gremlin> clear

When recursing in prolog, can one access variables from n amount of levels up?

To clarify what I mean, lets take this recursing example:
statement([]).
statement([A|B]):- A, statement(B).
The head, A is check by the rules my rules, and the tail B is sent to be recursed, which then becomes the head of level 2. When it recurses and is at the second level, how can I access the previous A? Am I thinking about it all wrong? If any clarification is needed please ask and I will do so. Thanks in advance.
What I am suppose to be testing for(type checker):
String s; int i; i = s.length(); // OK
or
String s; int i; s = i.length(); // fails
You have to record the previous statements explicitly such that at each iteration you will have access to the previous steps. It is up to you how do you record these statements. One solution would be:
statement(L) :- statement(L,[]).
statement([], _).
statement([A|B], L):- check(A), statement(B,[A|L]).
L records the preceding statements (in a reverse order).
Sure.. use the prolog database, assert and retract. This demonstrates it:
% Declare the lasthead fact as dynamic, so facts can change
:-dynamic lasthead/1.
% Set a starting value for the first iteration
lasthead(null).
statement([]).
statement([A|B]) :-
% Show the previous head
lasthead(LH),
writeln(['Last head was', LH]),
% Retract last head. ie. remove from the database
retract(lasthead(_)),
% Store the current head in the database
assertz(lasthead(A)),
% Recurse around
statement(B).
?- statement([a,b,c,d,e]).
[Last head was,null]
[Last head was,a]
[Last head was,b]
[Last head was,c]
[Last head was,d]
The above example uses retract to ensure there is only once lasthead(X) fact, but you could remove the retract which would ensure having multiple lasthead(X) facts, one for each list item.
You could then access/process multiple lasthead(X) facts using eg. findall(X, lasthead(X), Y), which would give you whichever lasthead(X) values you asserted along the way.

Resources