steven
steven

Reputation: 47

neo4j complex pattern searching

I'm new to NEO4J and I need help on a specific problem. Or an answer if it's even possible.

SETUP: We have 2 distinct type of nodes: users (A,B,C,D) and Products (1,2,3,4,5,6,7,8) Next we have 2 distinct type of relationships between users and products where a users WANTS a Product and where a product is OWNED BY a user.

  1. 1,2 is owned by A
  2. 3,4 is owned by B
  3. 5,6 is owned by C
  4. 7,8 is owned by D

Now

  1. B wants 1
  2. C wants 3
  3. D wants 5

So for now, I have no problems and I created the graph data with no difficulty. My questions starts here. We have a circle, when A wants product 8.

A-[:WANTS]->8-[:OWNEDBY]->D-[:WANTS]->5-[:OWNEDBY]->C-[:WANTS]->3-[:OWNEDBY]->B-[:WANTS]->1-[:OWNEDBY]->A

So we have a distinct pattern, U-[:WANTS]->P-[:OWNEDBY]->U

Now what I want to do is to find the paths toward the start node (initiating user that wants a product) following that pattern. How do I define this using Cypher? Or do I need another way?

Thanks upfront.

Upvotes: 2

Views: 994

Answers (2)

ulkas
ulkas

Reputation: 5918

i got a feeling this can be hacked with reduce and counting every even (every second) relationship:

MATCH p=A-[:OWNEDBY|WANTS*..20]->X
WITH r in relationships(p)
RETURN type(r),count(r) as cnt, 
WHERE cnt=10;

or maybe counting all paths where the number of rels is even:

MATCH p=A-[:OWNEDBY|WANTS*..]->X    
RETURN p,reduce(total, r in relationships(p): total + 1)  as tt
WHERE tt%2=0;

but you graph must have the strict pattern, where all incoming relationship from the set of ownedby and wants must be different from all outgoin relationships from the same set. in other words, this pattern can not exist: A-[:WANTS]->B-[:WANTS]->C or A-[:OWNEDBY]->B-[:OWNEDBY]->C

the query is probably wrong in syntax, but the logic can be implemented in cypher whn you will play more with it. or use gremlin, I think I saw somewhere a gremlin query, where you could define a pattern and than loop n-times via that pattern further till the end node.

Upvotes: 1

Stefan Armbruster
Stefan Armbruster

Reputation: 39915

I've played around with this and created http://console.neo4j.org/?id=qq9v1 showing the sample graph. I've found the following cypher statement solving the issue:

start a=node(1) 
match p=( a-[:WANTS]->()-[:WANTS|OWNEDBY*]-()-[:OWNEDBY]->a ) 
return p 
order by length(p) desc 
limit 1

There is just one glitch: the intermediate part [:WANTS|OWNEDBY*] does not mandate alternating WANT and OWNEDBY chains. As @ulkas stated, this should not be an issue if you take care during data modelling. You might also look into http://api.neo4j.org/current/org/neo4j/graphalgo/GraphAlgoFactory.html to apply graph algorithms from Java code. You might use unmangaged extensions to provide REST access to that.

Upvotes: 0

Related Questions