I have the following query which uses a mixture of cypher and py2neo ogm.
Is it possible to move the where clause into purely py2neo ogm syntax.
FeedItem.match(graph).where("(_)-[:SOURCE]->(:Feed {url:\"%s\"})"%feed.url)
In the documentation for match there do seem to be other options inside the match query. The example uses labels but there is also predicates which lead me to try something like the following:
FeedItem.match(graph,predicates=[RelatedTo(feed, "SOURCE")])
From https://py2neo.org/2021.0/ogm/index.html:
class py2neo.ogm.ModelMatch(graph, labels=frozenset({}),
predicates=(), order_by=(), skip=None, limit=None)
The relationship can be added in the Model object.
from py2neo.ogm import Model, Property, RelatedFrom
class Feed(Model):
name = Property("name")
url = Property("url")
subscribers = RelatedFrom("User", "SUBSCRIBED")
items = RelatedFrom("FeedItem", "SOURCE")
Then the query can be simplified from:
FeedItem.match(graph).where("(_)-[:SOURCE]->(:Feed {url:\"%s\"})"%feed.url)
to
feed.items
Related
I'm going to use Neo4j explicit/manual index queries, something like that:
MATCH (d:Decision)-[:HAS_VALUE_ON]->(ch:Characteristic)
WHERE ch.id = 2
CALL apoc.index.in(ch,'HAS_VALUE_ON','property.1.4:5 AND property.1.3:"practical"') YIELD node AS decision
MATCH (decision)-[ru:CREATED_BY]->(u:User)
RETURN decision, u
In order to use it I need to create the index query predicate based on Lucene query language, for instance like the following in the example above:
'property.1.4:5 AND property.1.3:"practical"'
According to my business logic, the values inside of the predicate come from UI and potentially can be used for Cypher(SQL) injections.
Previously I used Cypher named parameters in order to avoid this issue but looks like it doesn't work inside of predicate string.
How to deal with it in case of explicit/manual index Lucene query predicate?
I want to create a friends relation between abcd node and vbnm node having same node-name - Student
neo4j graph database visualization
I execute the following query, It doesn't show me any error but this query doesn't create any relation
match(Student:Stu),(Student:Stu)where Student.name="abcd" AND Student.name="vbnm" create(Student)-[fr:friends]->(Student)
You need use different variable name:
match(Student1:Stu),(Student2:Stu)
where Student1.name="abcd" AND
Student2.name="vbnm"
create(Student1)-[fr:friends]->(Student2)
I think you are confused by the syntax a little bit. Let me give you an example of a MATCH query syntax.
MATCH (variable1:Label),(variable2:Label) where variable1.foo = variable2.foo
You mixed label and variable in your query and each entity should have its own variable (variable1 and variable2) so you can interact with them.
So in your case the optimal query looks something like:
MATCH (s1:Student),(s2:Student ) where s1.name="abcd" AND s2.name="vbnm"
CREATE (s1)-[:friends]->(s2)
Note that you do not need to assign a variable to [:friends] relationship as you do not interact with it later in the same query.
I'm trying to make a social network and its my first web experience.
I'm using Neo4j database and py2neo module.
Now I want to find a node from my database and change some of it's properties.
I'm using the code below,and i can run it with no errors .but it doesn't change anything in my database and i have no idea why...
please help me if you can.
from py2neo import Graph
graph=Graph()
def edit_name(Uname,name):
person=graph.merge_one("Person","username",Uname)
person.cast(fname=name)
Cast is for casting general Python objects to py2neo objects. For example, if you wanted to cast a Python dictionary to a py2neo Node object, you'd do:
from py2neo import Graph, Node
graph = Graph()
d = {'name':'Nicole', 'age':24}
nicole = Node.cast('Person', d)
However, you still need to pass nicole to Graph.create to actually create the node in the database:
graph.create(nicole)
Then, if you later retrieve this node from the database with Graph.merge_one and want to update properties:
nicole = graph.merge_one('Person', 'name', 'Nicole')
nicole['hair'] = 'blonde'
Then you need to push those changes to the graph; cast is inappropriate for updating properties on something that is already a py2neo Node object:
nicole.push()
TL;DR:
from py2neo import Graph
graph = Graph()
def edit_username(old_name, new_name):
person = graph.merge_one('Person', 'username', old_name)
person['username'] = new_name
person.push()
merge_one will either return a matching node, or, if no matching node exists, create and return a new one. So, in your case, a matching node probably already exists.
I am starting to use py2neo and tried to work on some sample data sets. Here is (simplified) original set of queries:
CREATE (Ann:person{name:'Ann',gender:'female'})
CREATE (Target:store{name:'Target',location:'New York'})
CREATE (Ann)-[:PURCHASED {amount:'100',status:'denied'}]->(Target)
In py2neo I tried this:
ann,=graph_db.create(node({name:'Ann',gender:'female'}))
ann.add_labels("person")
target,=graph_db.create(node({name:'Target',location:'New York'}))
target.add_labels("merchant")
(ann,"PURCHASED",target,{'amount':'100', 'status':'denied'})
This query returns
(Node('http://localhost:7474/db/data/node/0'),
'PURCHASED',
Node('http://localhost:7474/db/data/node/3'),
{'amount': '100', 'status': 'denied'})
I have a lot of different users, so I wanted to find all of them whose transactions were denied
query_string="""
MATCH (customer:person)-[r:PURCHASED]->(merchant)
WHERE r.status = "denied"
RETURN customer.name as customer_name
"""
Then I try to execute it
result = neo4j.CypherQuery(graph_db, query_string).execute()
It returns an empty object. What am I doing wrong?
I suggest, when creating a node or a relationship, to use merge_one and create_unique respectively in order to ensure you won't create any duplicates.
E.g:
x=graph.merge_one("Boy","Name",bname)
y=graph.merge_one("Girl","Name",gname)
likes=Relationship(x, "LIKES", y)
graph.create_unique(likes)
I have imported freebase dump to neo4j. But currently i am facing issue with get queries because of size of db. While import i just created node index and indexed URI property to index for each node. For each node i am adding multiple properties like label_en, type_content_type_en.
props.put(URI_PROPERTY, subject.stringValue());
Long subjectNode = db.createNode(props);
tmpIndex.put(subject.stringValue(), subjectNode);
nodeIndex.add(subjectNode, props);
Now my cypher queries are like this. Which are timing out. I am unable to add index on label_en property. Can anybody help?
match (n)-[r*0..1]->(a) where n.label_en=~'Hibernate.*' return n, a
Update
BatchInserter db = BatchInserters.inserter("ttl.db", config);
BatchInserterIndexProvider indexProvider = new LuceneBatchInserterIndexProvider(db);
BatchInserterIndex index = indexProvider.nodeIndex("ttlIndex", MapUtil.stringMap("type", "exact"));
Question: When i have added node in nodeindex i have added with property URI
props.put(URI_PROPERTY, subject.stringValue());
Long subjectNode = db.createNode(props);
nodeIndex.add(subjectNode, props);
Later in code i have added another property to node(Named as label_en). But I have not added or updated nodeindex. So as per my understanding lucene does not have label_en property indexed. My graph is already built so i am trying to add index on label_en property of my node because my query is on label_en.
Your code sample is missing how you created your index. But I'm pretty sure what you're doing is using a legacy index, which is based on Apache Lucene.
Your Cypher query is using the regex operator =~. That's not how you use a legacy index; this seems to be forcing cypher to ignore the legacy index, and have the java layer run that regex on every possible value of the label_en property.
Instead, with Cypher you should use a START clause and use the legacy indexing query language.
For you, that would look something like this:
START n=node:my_index_name("label_en:Hibernate.*")
MATCH (n)-[r*0..1]->(a)
RETURN n, a;
Notice the string label_en:Hibernate.* - that's a Lucene query string that says to check that property name for that particular string. Cypher/neo4j is not interpreting that; it's passing it through to Lucene.
Your code didn't provide the name of your index. You'll have to change my_index_name above to whatever you named it when you created the legacy index.