Dimitrios Kontoulis
Dimitrios Kontoulis

Reputation: 420

Neo4j Cypher query error

I am facing an issue while I am trying to execute a query in neo4j.

The expected result is to get the products that belong to a certain marketplace and have relation to ProductFeed, starting from marketplace

Query

MATCH (marketplace:`Marketplace`), 
(marketplace)-[rel_has_product_products:HAS_PRODUCT]->(products:`Product`),
 (product:`Product`), 
(product)-[rel_has_product_feed_productFeed:HAS_PRODUCT_FEED]->(productFeed:`ProductFeed`) 
WITH product, 
count(productFeed) AS productFeed_count
 WHERE id(marketplace) = 123481 
and productFeed_count >= 1 
RETURN product 

The error I get is marketplace not defined (line 1... at id(marketplace) =

I don't see why marketplace is not defined

Upvotes: 0

Views: 528

Answers (4)

InverseFalcon
InverseFalcon

Reputation: 30417

While everyone else is correct that the fix for the problem in your question is to include marketplace in your WITH clause to keep it in scope, there's a more serious problem with your query that's being overlooked.

You have a match from a marketplace to products:Products, but you never actually use the products variable again in the entire query. Instead, you have a separate match to a new product variable that's matching to all :Products. You aren't constraining the products you're working with to a particular marketplace at all.

So let's fix this. There are also a number of other improvements to make:

  1. We should also make sure we constrain marketplace to the marketplace you want early, not at the end.
  2. We can get rid of any variables you aren't going to use, so let's ditch the relationship variables.
  3. You seem to only be matching from a product to its product feed for the sole purpose of making sure it has a product feed. We can do this easier and sooner by making this part of the WHERE clause on the first MATCH, making sure the products we match on have a product feed.

All of this makes for much more concise and efficient query.

MATCH (marketplace:`Marketplace`)-[:HAS_PRODUCT]->(product:`Product`)
WHERE id(marketplace) = 123481 AND (product)-[:HAS_PRODUCT_FEED]->(:`ProductFeed`)
RETURN product 

Upvotes: 1

Stefan Gehrig
Stefan Gehrig

Reputation: 83672

The problem here is that you're using a WITH clause to connect different sub queries. Only variables that are explicitly stated in the WITH clause are carried forward to the next clause.

MATCH (marketplace:`Marketplace`) ...
WITH product, count(productFeed) AS productFeed_count
WHERE id(marketplace) = 123481 and productFeed_count >= 1 
RETURN product 

You're not carrying marketplace into the WITH clause. So the correct way would be to either add the WHERE condition to the initial MATCH or carry marketplace into the WITHclause:

MATCH (marketplace:`Marketplace`), 
    (marketplace)-[rel_has_product_products:HAS_PRODUCT]->(products:`Product`),
    (product:`Product`), 
    (product)-[rel_has_product_feed_productFeed:HAS_PRODUCT_FEED]->(productFeed:`ProductFeed`) 
WHERE id(marketplace) = 123481 
WITH product, count(productFeed) AS productFeed_count
WHERE productFeed_count >= 1 
RETURN product

or

MATCH (marketplace:`Marketplace`), 
    (marketplace)-[rel_has_product_products:HAS_PRODUCT]->(products:`Product`),
    (product:`Product`), 
    (product)-[rel_has_product_feed_productFeed:HAS_PRODUCT_FEED]->(productFeed:`ProductFeed`) 
WITH marketplace, product, count(productFeed) AS productFeed_count
WHERE id(marketplace) = 123481 AND productFeed_count >= 1 
RETURN product

It seems as if option (1) would be the better way from a performance perspective as it eliminates unneeded paths (those not starting a marketplace 123481) very early in the process.

Upvotes: 1

Mit Bhatt
Mit Bhatt

Reputation: 482

You have only taken product in WITH clause. marketplace should also be taken to further process.

Modified query

MATCH (marketplace:`Marketplace`), 
(marketplace)-[rel_has_product_products:HAS_PRODUCT]->(products:`Product`),
 (product:`Product`), 
(product)-[rel_has_product_feed_productFeed:HAS_PRODUCT_FEED]->(productFeed:`ProductFeed`) 
WITH product, marketplace,
count(productFeed) AS productFeed_count
 WHERE id(marketplace) = 123481 
and productFeed_count >= 1 
RETURN product 

Upvotes: 1

oskar alfons
oskar alfons

Reputation: 76

marketplace is not defined as variable, you should pass it in the WITH clause

MATCH (marketplace:`Marketplace`), 
(marketplace)-[rel_has_product_products:HAS_PRODUCT]->(products:`Product`),
 (product:`Product`), 
(product)-[rel_has_product_feed_productFeed:HAS_PRODUCT_FEED]->(productFeed:`ProductFeed`) 
WITH product, marketplace, 
count(productFeed) AS productFeed_count
 WHERE id(marketplace) = 123481 
and productFeed_count >= 1 
RETURN product 

Upvotes: 1

Related Questions