cancel
Showing results for 
Search instead for 
Did you mean: 

Is i tpossible to limit the answer of a "pre-query" based on some relation property?

xpegenaute
Node

Hi all,

I am interested to create a query which includes a "subquery" and I want to limit the output of the subquery based on some criteria. Much more cleat with an example (The sample database can be found below):

The query I am using now is this:

MATCH (a:A {name:"A1"})-[:IN_REL_AB]->(b:B)-[w:IN_REL_BC]->(c:C)
RETURN c.name, w.weight, b.name;

The current output is:

+----------------------------+
| c.name | w.weight | b.name |
+----------------------------+
| "C5"   | 5        | "B2"   |
| "C4"   | 4        | "B2"   |
| "C3"   | 3        | "B1"   |
| "C2"   | 2        | "B1"   |
| "C1"   | 1        | "B1"   |
+----------------------------+

I want to be able to filter based on the weight field defined in "IN_REL_BC". For example the two biggest weight of B1 and B2. The output could be like:

+----------------------------+
| c.name | w.weight | b.name |
+----------------------------+
| "C5"   | 5        | "B2"   |
| "C4"   | 4        | "B2"   |
| "C3"   | 3        | "B1"   |
| "C2"   | 2        | "B1"   |
+----------------------------+

Is it possible to do with cypher ?

The content of the sample database is:

CREATE (:A {name:"A1"});

CREATE (:B {name:"B1"});
CREATE (:B {name:"B2"});

CREATE (:C {name:"C1"});
CREATE (:C {name:"C2"});
CREATE (:C {name:"C3"});
CREATE (:C {name:"C4"});
CREATE (:C {name:"C5"});

MATCH (a:A {name:"A1"})
MATCH (b:B {name:"B1"})
CREATE (a)-[:IN_REL_AB]->(b);

MATCH (a:A {name:"A1"})
MATCH (b:B {name:"B2"})
CREATE (a)-[:IN_REL_AB]->(b);

MATCH (b:B {name:"B1"})
MATCH (c:C {name:"C1"})
CREATE (b)-[:IN_REL_BC {weight: 1}]->(c);

MATCH (b:B {name:"B1"})
MATCH (c:C {name:"C2"})
CREATE (b)-[:IN_REL_BC {weight: 2}]->(c);

MATCH (b:B {name:"B1"})
MATCH (c:C {name:"C3"})
CREATE (b)-[:IN_REL_BC {weight: 3}]->(c);

MATCH (b:B {name:"B2"})
MATCH (c:C {name:"C4"})
CREATE (b)-[:IN_REL_BC {weight: 4}]->(c);

MATCH (b:B {name:"B2"})
MATCH (c:C {name:"C5"})
CREATE (b)-[:IN_REL_BC {weight: 5}]->(c);

3 REPLIES 3

intouch_vivek
Graph Steward

Hi @xpegenaute,

Welcome to Community!!
I really appreciate you quoted your question with good example and dataset.
I tried the query you looking for and reached nearer to that.
MATCH (a:A {name:"A1"})-[:IN_REL_AB]->(b:B)-[w:IN_REL_BC]->(c:C)
With b.name as bName, collect(distinct w.weight) as weights
with bName, collect(reduce(a='',w in weights|substring(a+w+',',0,3))) as k return bName,k

xpegenaute
Node

Hi,

Ok, I see your solution but I guess it does not work for my case which is much bigger than this simple db.

What I suspect is that probably I should not try to create one superpowerfull query and split the query in several little queries. Does it make sense ?, is it a good rule of thumb ?, may be I should profile the queries and balance the memory/time consumption to choose which path to follow ?

Regards,
Xavi

My solution gives
B2-----["5","4"]
B1-----["3","2"]

But yes it does not transform into multiple rows