Search code examples
pythonneo4jcypherpy2neo

How to have a py2neo cypher query take in arguments from python?


Overarching background
I am currently attempting to write neo4j queries into functions to be used in flask.
I am aiming to have the function load the data from a csv file that updates itself periodically and create new nodes and relationships as needed. Afterwards, users would be able to enter search terms related to the title of their article and find keywords related to their article using the Jaccard similarity method.

I have been attempting to follow the function structure shown here:
https://github.com/nicolewhite/neo4j-flask/blob/master/blog/models.py

I have tested neo4j cypher queries separately, and I am currently trying to have py2neo take user input as a search term and add to my cypher query to find similar keywords.

My title csv data structure is as follows:

title_id,title  
T1,ArticleTitle1  
T2,ArticleTitle2 

My keyword csv file looks like this:

title_id,keyword_id,keyword  
T1,K1,aaa  
T1,K2,bbb  
T1,K3,ccc  
T1,K4,ddd  
T2,K1,aaa  
T2,K5,eee  
T2,K6,fff  
T2,K4,ddd  

Currently, my py2neo code looks like this:

from py2neo import Graph, Node, Relationship

from datetime import datetime
import os
import uuid

url = os.environ.get('GRAPHENEDB_URL', 'http://localhost:7474')

graph = Graph(url + '/db/data/', username="****", password="****")


class Keyword:    
    def jaccard_kw_rec(self, search):
        query2 = '''MATCH (p:Title)-[:SIMILAR]->(other),
                (other)-[:HAS_KEYWORDS]->(keyword)  
                WHERE not((p)-[:HAS_KEYWORDS]->(keyword)) and p.Title contains {self.search}
                RETURN keyword AS keywords
                '''
        return graph.run(query2)

I've copied the form of the functions but after running into errors (python still sees my query as just a string) I'm a bit lost as to where I should go on from here.

Thank you very much,

Eric


Solution

  • For my specific problem I found that the following works for me:

    def jacc_kw_rec(search):
        q_r = []
        query2 = "MATCH (p:Title)-[:SIMILAR]->(other), (other)-[:HAS_KEYWORDS]->(keyword) " \
                 "WHERE not((p)-[:HAS_KEYWORDS]->(keyword)) and p.Title contains \"{}\"".format(
            search) + "RETURN keyword AS keywords LIMIT 3"
    
        result = graph.run(query2).data()
        for r in result:
            r_j = json.dumps(r)
            loaded_r = json.loads(r_j)
            kw_ex = loaded_r['keywords']['Keyword']
            q_r.append(kw_ex)
        return q_r
    

    Essentially, a combination of string concatenation and the .format() function.