I am not very familiar with Neo4j because I just used it for several days.
But now I want to find path between two nodes
like path : A & D
A -> B -> C -> D
A -> B -> E -> D
A -> C -> E -> D
and using "WHERE NOT" to eliminate Node B
so I will leave path A -> C -> E -> D
is there any way I can do this ?
Here is my Cypher:
MATCH (home { name:'Grove' }),(school { name:'Moulton' }),(Ann {name:'Ann'}),
p = ((home)-[*..4]->(school))
WHERE NOT ((home)-[]->(Ann))
RETURN p
It's not working for me
You can use the NONE predicate in the WHERE clause to filter out paths containing the B node. See http://console.neo4j.org/?id=hppthl for an example.
The cypher statement looks like this:
MATCH p=(:Person { name:'A' })-[:KNOWS*..4]->(:Person { name:'D' }),
(without:Person { name:'B' })
WHERE NONE (x IN nodes(p) WHERE x=without)
RETURN p
Related
Say I have the following graph:
(:A) -> (:B {hasAttr: 'yes'}) -> (:C) -> (:B {hasAttr: 'yes'})
I want to find out the path between node type A and node type B. But I only need the path that contains one node type B. So the query return should be
(:A) -> (:B {hasAttr: 'yes'})
What is the right query?
You can use the SINGLE() predicate function (see https://neo4j.com/docs/cypher-manual/current/functions/predicate/#functions-single)
MATCH p = ...
WHERE SINGLE(node IN nodes(p) WHERE node:B)
Graphileon is correct. Use the function SINGLE() to return nodes with exactly one node that has a property.hasAttr = 'yes'. Below is a working query.
MATCH
p = (:A)-->(:B)
WHERE
single(var IN nodes(p) WHERE var.hasAttr = 'yes')
RETURN p
Sample graph found in https://neo4j.com/docs/cypher-manual/current/functions/predicate/#functions-single
MATCH p = (n)-->(b)
WHERE
n.name = 'Alice'
AND single(var IN nodes(p) WHERE var.eyes = 'blue')
RETURN p
Result:
╒══════════════════════════════════════════════════════════════════════╕
│"p" │
╞══════════════════════════════════════════════════════════════════════╡
│[{"name":"Alice","eyes":"brown","age":38},{},{"name":"Bob","eyes":"blu│
│e","age":25}] │
└──────────────────────────────────────────────────────────────────────┘
If I have two graphs
a:Test -> b:Foo({type = 'car'}) -> c:Test -> d:Foo({type = 'car'}) -> e:Test
a:Test -> b:Foo({type = 'car'}) -> c:Test -> d:Foo({type = 'bike'}) -> e:Test
I want to write a shortest path query that will match the first path predicated on intermediate nodes of type Foo with type = car, but then fails to find the second a path in the second graph.
MATCH (a:Test {id: '1'} ),
(e:Test {id: '5'}),
p = shortestPath((a)-[:REL*]-(e))
WHERE all(r IN nodes(p) WHERE r.type = 'car')
RETURN p
But this obviously doesn't work, maybe with a subquery?
Not sure how optimized this is, but it probably does the job. Basically we introduce a nested list comprehension syntax:
MATCH (a:Test {id: '1'} ),
(e:Test {id: '5'}),
p = shortestPath((a)-[:REL*]-(e))
WHERE all(r IN [x in nodes(p) where x:Foo] WHERE r.type = 'car')
RETURN p
I Have a node called Member it has Relationships to Clubs and Shops I want to create a query so that I can return Member with Clubs and Shops
MATCH (m: Member { username: $memberUsername ,
password: $password})<- [r: MEMBER_BELONGS_TO_CLUBS] - (c: Club)
RETURN m, c, r
in the example I get Member and Clubs but I want to get member Clubs and member Shops
If your node M is connected like this S -> M <- C (M is Member, S is Shop, and C is Club), then you can use query similar like example in 4.2 Multiple Relationships in documentation:
MATCH (s: Shop) - [rs: MEMBER_BELONGS_TO_SHOPS] ->
(m: Member { username: $memberUsername ,
password: $password}) <- [r: MEMBER_BELONGS_TO_CLUBS] - (c: Club)
RETURN m, c, r, s, rs
Also you can use syntax like in this example with multiple MATCH:
MATCH (m: Member { username: $memberUsername ,
password: $password})
MATCH (s: Shop) - [rs: MEMBER_BELONGS_TO_SHOPS] -> (m)
MATCH (m) <- [r: MEMBER_BELONGS_TO_CLUBS] - (c: Club)
RETURN m, c, r, s, rs
And both queries returns something only if M is connected with both S and C. If you
don't want that restrictions you can use OPTIONAL MATCH documentation.
Given the type for a tree:
type id = int;;
type tree = T of id * tree list;;
let ex = T(12,[T(3,[T(4,[T(38,[])])]);T(23,[T(22,[])]);T(1,[])]);;
Given that all id's are unique I would like to get a tree from a given id like so:
get 23 ex = t(23, [t(22,[])]);
So far I only been able to make a function like this:
let rec child c n =
match c with
| [] -> []
| e::es -> (get n e) # (child es n)
and get id t =
match t with
| T(id1,c) when id=id1-> [t]
| T(_,c) -> child c id;;
Which is fine, but the function does a total run through of all nodes in the tree. Is it possible to make a function that terminates when it finds the right node and thereby skips some computations?
You would need to make the recursive call return a value that somehow contains the response about whether it found the node. If it did - just return it, if it didn't - keep (recursively) searching the rest of the tree.
To do this, F# has a handy built-in type - Option. It's a sum type defined as type Option<'t> = Some of 't | None. So I would make the get function return an Option<tree> rather than tree list, and then the child function can decide whether it wants to proceed:
let rec child c n =
match c with
| [] -> None
| e::es -> match get n e with
| Some x -> Some x // node found - just return it
| None -> child es n // not found - keep searching
and get id t =
match t with
| T(id1,c) when id=id1-> Some t
| T(_,c) -> child c id;;
Also note that your child function is actually available in the standard library under the name of List.tryPick:
let rec child c n = List.tryPick (get n) c
Which makes the whole thing collapse into this:
let rec get id t =
match t with
| T(id1,_) when id=id1 -> Some t
| T(_,c) -> List.tryPick (get id) c
I'm trying to follow the code for McBride's How to Keep Your Neighbours in Order, and can't understand why Agda (I'm using Agda 2.4.2.2) gives the following error message:
Instance search can only be used to find elements in a named type
when checking that the expression t has type .T
for function _:-_ . The code is given bellow
data Zero : Set where
record One : Set where
constructor <>
data Two : Set where tt ff : Two
So : Two -> Set
So tt = One
So ff = Zero
record <<_>> (P : Set) : Set where
constructor !
field
{{ prf }} : P
_=>_ : Set -> Set -> Set
P => T = {{ p : P }} -> T
infixr 3 _=>_
-- problem HERE!
_:-_ : forall {P T} -> << P >> -> (P => T) -> T
! :- t = t
Any help is highly appreciated.
There was a recent email by Nils Anders Danielsson at the agda-dev mailing list precisely about this. I cannot find it online, so here is a quote:
Conor uses lots of instance arguments in "How to Keep Your Neighbours
in Order". However, his code was written using the old variant of the
instance arguments, and fails to check now. I managed to make the code
work again using some small tweaks, and wonder if we could get away
with even less:
I replaced
record One : Set where constructor it
with
record One : Set where
instance
constructor it.
This seems fine with me.
I replaced
_:-_ : forall {P T} -> <P P P> -> (P => T) -> T
! :- t = t
with
_:-_ : forall {P T} -> <P P P> -> (P => T) -> T
! {{prf = p}} :- t = t {{p = p}},
because "Instance search can only be used to find elements in a
named type". Similarly, in two cases I replaced a module parameter
(L : REL P)
with
(L' : REL P) (let L = Named L'),
where Named is a named type family:
data Named {P : Set} (A : REL P) : REL P where
named : forall {x} -> A x -> Named A x