Query working in Neo4j Browser but not in Python Driver

Hi everyone, I am working on a recommender system. I am trying first some basic queries. I am stuck with the following query that works on the Neo4j Browser but it does not in Python:

"MATCH (client:Client{id:$client_id})-[:SELLS]-(product:Product{id:$product_id})"
                    "MATCH (product)-[:IN_CATEGORY]->(:Category)<-[:IN_CATEGORY]-(rec:Product)<-[i:INCLUDES]-()"
                    "WITH sum(i.quantity) AS quantity, rec.name AS recommendation"
                    "RETURN recommendation, quantity  ORDER BY quantity DESC"

Python gives me the following error message:

{code: Neo.ClientError.Statement.SyntaxError} {message: Invalid input 'c': expected 'm/M' or 't/T' (line 1, column 239 (offset: 238))

This query is inside a function where I declare both parameters. It is quite similar to a category recommendation with almost the same structure.

This is the query that works on Neo4j browser:

MATCH (client:Client{id:$clientId})-[:SELLS]-(product:Product{id:$productId})
MATCH (product)-[:IN_CATEGORY]->(:Category)<-[:IN_CATEGORY]-(rec:Product)<-[i:INCLUDES]-(order:Order)
WITH sum(i.quantity) AS quantity, rec.name AS recommendation
RETURN recommendation, quantity  ORDER BY quantity DESC

I cannot understand why the Neo4j Browser can execute the query but Python can't.

Hello @samsitta :slight_smile:

Did you try to write the query on one line instead of 4? Just to check if it's from the syntax or the query itself.

Regards,
Cobra

No, I wrote the query on 4 lines as well.

How are your parameters defined in Python? I would expect the syntax to be something like shown in the answer here, rather than using $:

Hello @samsitta

  • $var is the right way to define arguments in a query
  • are you using the Neo4j Python driver or py2neo?
  • can you try to write the query on one line?
  • if you still want to use several lines, you should put spaces at the end of the first three lines:
"MATCH (client:Client{id:$client_id})-[:SELLS]-(product:Product{id:$product_id}) "
"MATCH (product)-[:IN_CATEGORY]->(:Category)<-[:IN_CATEGORY]-(rec:Product)<-[i:INCLUDES]-() "
"WITH sum(i.quantity) AS quantity, rec.name AS recommendation "
"RETURN recommendation, quantity  ORDER BY quantity DESC"

Regards,
Cobra

I am using Neo4j Python Driver. I actually have already used two very similar queries and had not problem at all. I will try your suggestion to use your suggestion to use one line instead. I am using spaces at the end of the first three lines already.

Thank you, I tried your suggestion and it worked with writing the query on one line. Do you have any idea why it is failing when I try to write it as four lines?

No problem :slight_smile: could I see the Python function?

Sure, this is the one that finally worked:

def best_sellers(tx, client_id, product_id):
    recommendations = []
    result = tx.run("MATCH (client:Client{id:$client_id})-[:SELLS]->(product:Product{id:$product_id}) MATCH (product)-[:IN_CATEGORY]->(:Category)<-[:IN_CATEGORY]-(rec:Product)<-[i:INCLUDES]-() WITH sum(i.quantity) AS quantity, rec.name AS recommendation RETURN recommendation ORDER BY quantity DESC", client_id = client_id, product_id = product_id)
    for item in result:
        recommendations.append(item["recommendation"])
    return recommendations

with driver.session() as session:
    recommendations = session.read_transaction(best_sellers, client_id, product_id)
    for recommendation in recommendations:
        print(recommendation)```

Normally, these formats should work:

  • put the query on one line;
  • put the query on several lines with the triple """ at the beginning and at the end of the query;
  • put the query on several lines with one " at the beginning and at the end of each line without forgetting to put a space at the end of each line (not mandatory for the last line) like in the example of the doc.

Which version of the driver are you using?

For example, I am using this function and it is working just fine:

def same_category_recommendation(tx, client_id, product_id):
    recommendations = []
    result = tx.run("MATCH (client:Client{id:$client_id})-[:SELLS]-(product:Product{id:$product_id})"
                    "MATCH (product)-[:IN_CATEGORY]->(:Category)<-[:IN_CATEGORY]-(rec:Product)"
                    "RETURN rec.name AS recommendation", client_id = client_id, product_id = product_id)
    for item in result:
        recommendations.append(item["recommendation"])
    return recommendations

with driver.session() as session:
    recommendations = session.read_transaction(same_category_recommendation, client_id, product_id)
    for recommendation in recommendations:
         print(recommendation)

I am using neo4j==4.1.1

Indeed, that's weird, I have no more ideas but at least you have a solution when it doesn't work.

You can still create the string query before and put your query in and after call it in tx.run() :slight_smile:

Thx! I might do that :smiley: