Arthur Johnson
Arthur Johnson

Reputation: 45

Find nodes in Neo4j that are at the end of all paths and not in another

We are in a POC for Neo4j. The use case is a dashboard where we only bring back opportunities for a seller that they are qualified for and have not already taken an action on. Currently there are 3 criteria and we are looking to add two more. The corresponding SQL is 3 pages so we are looking at a better way as when we add the next criteria, 2 more nodes paths in Neo, will be a bear in SQL. When I run the query below I get back a different amount of rows than the SQL. the buys returned must be at the end of all 3 paths and not be in the 4th. I hope you can point out where I went wrong. If this is a good query then I have a data problem.

Here is the query:

//oportunities dashboard
MATCH (s:SellerRep)-[:SELLS]->(subCat:ProductSubCategory)<-[:IS_FOR_SUBCAT]-(b:Buy)
MATCH (s:SellerRep)-[:SELLS_FOR]->(o:SellerOrg)-[:HAS_SELLER_TYPE]->(st:SellerType)<-[:IS_FOR_ST]-(b:Buy)
MATCH (s:SellerRep)-[:SELLS_FOR]->(o:SellerOrg)-[:IS_IN_SC]->(sc:SellerCommunity)<-[:IS_FOR_SC]-(b:Buy)
WHERE NOT  (s:SellerRep)-[:PLACED_BID]->(:Bid)-[:IS_FOR_BUY]->(b:Buy)
AND s.sellerRepId = 217722 and b.currBuyStatus = 'Open'
RETURN b.buyNumber, b.buyDesc, st.sellerType, sc.communtiyName, subCat.subCategoryName+' - '+subCat.desc as sub_cat

If it helps, here is the data model: POC Data model

Thanks for any help.

Upvotes: 0

Views: 48

Answers (1)

cybersam
cybersam

Reputation: 66989

A WHERE clause only filters the immediately preceding MATCH clause.

Since you placed your WHERE clause after the third MATCH clause, the first 2 MATCH clauses are not bound to a specific SellerRep or Buy node, and are therefore bringing in more ProductSubCategory and SellerType nodes than you intended.

The following query is probably closer to what you intended:

MATCH (s:SellerRep)-[:SELLS]->(subCat:ProductSubCategory)<-[:IS_FOR_SUBCAT]-(b:Buy)
WHERE s.sellerRepId = 217722 AND b.currBuyStatus = 'Open' AND NOT (s:SellerRep)-[:PLACED_BID]->(:Bid)-[:IS_FOR_BUY]->(b:Buy)
MATCH (s)-[:SELLS_FOR]->(o:SellerOrg)-[:HAS_SELLER_TYPE]->(st:SellerType)<-[:IS_FOR_ST]-(b)
MATCH (o)-[:IS_IN_SC]->(sc:SellerCommunity)<-[:IS_FOR_SC]-(b)
RETURN b.buyNumber, b.buyDesc, st.sellerType, sc.communtiyName, subCat.subCategoryName+' - '+subCat.desc as sub_cat

NOTE: Your second and third MATCH clauses both started with (s:SellerRep)-[:SELLS_FOR]->(o:SellerOrg). I simplified the same logic by having my third MATCH clause just start with (o). Hopefully, you actually intended to force both clauses to refer to the same SellerOrg node.

Upvotes: 1

Related Questions