How to create multiple node via looping in py2neo for neo4j - neo4j

Kindly help me to resolve this issue. I am following the tutorial on this link: https://www.kernix.com/blog/an-efficient-recommender-system-based-on-graph-database_p9 . I am unable to modify the following so that it could comply with the new format of py2neo v3 where graph.run is used instead of graph.cypher.begin(). The purpose of the code below is to Create the nodes relative to Users, each one being identified by its user_id and "MERGE" request : creates a new node if it does not exist already
tx = graph.cypher.begin()
statement = "MERGE (a:`User`{user_id:{A}}) RETURN a"
for u in user['id']:
tx.append(statement, {"A": u})
tx.commit()
Thank you very much in advance

With v3 of py2neo your snippet would look like this:
tx = graph.begin()
statement = "MERGE (a:`User`{user_id:{A}}) RETURN a"
for u in user['id']:
tx.run(statement, {"A": u})
tx.commit()
begin() is a method on the Graph class, which will create a new transaction.
Transaction.run will send a Cypher statement to the server for execution - but not commit the transaction until Transaction.commit is called.

Related

How to verify if a node exist and if not exist then a created during an import of .csv to neo4j

I am importing some .cvs files for my database in neo4j, but I have the data of people in three different files, so when I import the data of the person from another file that has more data, I get an error when trying to import people nodes, because I already have other nodes with those dni (constraint) in my database.
So I want to create the new node or, if it exists, retrieve its pointer to create relationships with other nodes that I keep creating while I import.
I have tried several things on the internet but I still can't find the solution
Here my code:
LOAD CSV WITH HEADERS FROM 'file:/D:/ACCOUNT.csv' AS line FIELDTERMINATOR ';'
MERGE (persona :Persona { dni: line.DNI,
nombre: line.NOMBRE,
sexo: line.SEXO,
fechaNacimiento: line.FNACIMIENTO,
direccion: line.DIRECCION
})
I have tried with apoc and "with" but I still can't find the solution.
when this code finds another node with a person label and ID equal to the one entered, it gives me an error
To get this working, you'll have to understand how MERGE works. The statement
MERGE (persona :Persona { dni: line.DNI, nombre: line.NOMBRE, sexo: line.SEXO,
fechaNacimiento: line.FNACIMIENTO,direccion: line.DIRECCION
})
will create a new Persona node for every distinct combination of the above properties. So, for a node with the same dni, but with other values of other properties, this will fail. To fix this, you should try merging the nodes on the basis of their dni, and then set the properties like this:
MERGE (persona :Persona { dni: line.DNI })
ON CREATE
SET persona.nombre = line.NOMBRE,
persona.sexo = line.SEXO,
persona.fechaNacimiento = line.FNACIMIENTO,
persona.direccion = line.DIRECCION
The above query will ignore setting properties if a matching node is found. To set some properties when a match is found, use ON MATCH, like this:
MERGE (persona :Persona { dni: line.DNI })
ON CREATE
SET persona.nombre = line.NOMBRE,
persona.sexo = line.SEXO,
persona.fechaNacimiento = line.FNACIMIENTO,
persona.direccion = line.DIRECCION
ON MATCH
// Matching logic here

Neo4j cypher query fails with unknown syntax error

I have the following paramObj and dbQuery
paramObj = {
email: newUser.email,
mobilenumber: newUser.telephone,
password: newUser.password,
category: newUser.category,
name: newUser.name,
confirmuid: verificationHash,
confirmexpire: expiryDate.valueOf(),
rewardPoints: 0,
emailconfirmed: 'false',
paramVehicles: makeVehicleArray,
paramVehicleProps: vehiclePropsArray
}
dbQuery = `CREATE (user:Person:Owner {email:$email})
SET user += apoc.map.clean(paramObj,
['email','paramVehicles','paramVehiclesProps'],[])
WITH user, $paramVehicles AS vehicles
UNWIND vehicles AS vehicle
MATCH(v:Vehicles {name:vehicle})
CREATE UNIQUE (user)-[r:OWNS {since: timestamp()}]->(v)
RETURN user,r,v`;
Then I tried to execute
commons.session
.run(dbQuery, paramObj)
.then(newUser => {
commons.session.close();
if (!newUser.records[0]) {........
I am getting
Error: {"code":"Neo.ClientError.Statement.SyntaxError","name":"Neo4jError"}
which doesn't direct me anywhere. Can anyone tell me what am I doing wrong here?
This is actually the first time I am using the query format .run(dbQuery, paramObj) but this format is critical to my use case. I am using Neo4j 3.4.5 community with apoc plugin installed.
Ok...so I followed #inversFalcon suggestion to test in browser and came up with following parameters and query that closely match the ones above:
:params paramObj:[{ email:"xyz123#abc.com", mobilenumber:"8711231234",password:"password1", category:"Owner",name:"Michaell",vehicles:["Toyota","BMW","Nissan"],vehicleProps: [] }]
and query
PROFILE
CREATE (user:Person:Owner {email:$email})
SET user += apoc.map.clean($paramObj, ["email","vehicles","vehicleProps"],[])
WITH user, $vehicles AS vehicles
UNWIND vehicles AS vehicle
MATCH(v:Vehicles {name:vehicle})
MERGE (user)-[r:OWNS {since: timestamp()}]->(v)
RETURN user,r,v;
Now I get
Neo.ClientError.Statement.TypeError: Can't coerce `List{Map{name -> String("Michaell"), vehicles -> List{String("Toyota"), String("BMW"), String("Nissan")},.......
I also reverted to neo4j 3.2 (re: an earlier post by Mark Needham) and got the same error.
You should try doing an EXPLAIN of the query using the browser to troubleshoot it.
A few of the things I'm seeing here:
You're referring to paramObj, but it's not a parameter (rather, it's the map of parameters you're passing in, but it itself is not a parameter you can reference in the query). If you need to reference the entire set of parameters being passed in, then you need to use nested maps, and have paramObj be a key in the map that you pass as the parameter map (and when you do use it in the query, you'll need to use $paramObj)
CREATE UNIQUE is deprecated, you should use MERGE instead, though be aware that it does behave in a different manner (see the MERGE documentation as well as our knowledge base article explaining some of the easy-to-miss details of how MERGE works).
I am not sure what caused the coercion error to disappear but it did with the same query and I got a "expected parameter error" this was fixed by using $paramObj.email, etc. so the final query looks like this:
CREATE (user:Person:Owner {email: $paramObj.email})
SET user += apoc.map.clean($queryObj, ["email","vehicles","vehicleProps"],[])
WITH user, $paramObj.vehicles AS vehicles
UNWIND vehicles AS vehicle
MATCH(v:Vehicles {name:vehicle})
MERGE (user)-[r:OWNS {since: timestamp()}]->(v)
RETURN user,r,v;
which fixed my original problem of how to remove properties from a map when using SET += map.

Create a relationship only if a similar one exist - neo4j

I have a linked list such that every node has a 'next' relation pointed to the next node, the first node has another relation : 'first' which pointed to it from some category. I'm trying to write a delete function that uses cypher to do so but I keep getting this error :
Received an unexpected HTTP status when executing the request.
The query was: MATCH (c:Cat {id:{id}})-[:Post]->(p:Post{id:{pid}})
My try :
gclient.Cypher
.Match("(c:Cat {id:{id}})-[:Post]->(p:Post{id:{pid}})")
.Match("(p)-[nn:next]->(np:Post)")
.OptionalMatch("(c)-[old:first]->(p)")
.OptionalMatch("(ppost:Post)-[pn:next]->(p)")
.WithParams((new
{
id = catId,
pid = postId
}))
.Create("(ppost)-[:next]->(np)")
.With("old, p, c, np")
.Where("old IS NOT NULL")
.Create("(c)-[:first]->(np)")
.With("p, old")
.Delete("old")
.Delete("p")
.ExecuteWithoutResults();

struggling with error on py2neo simple script

I've been trying to create a graph using py2neo / neo4j but I'm constantly hitting problems with my script. The latest one being the following...
(bare in mind that i am also new to python. sorry!)
Here is the code:
from py2neo import neo4j, node
graph = neo4j.GraphDatabaseService("http://localhost:7474/db/data/")
graph.clear()
i_word = graph.get_or_create_index(neo4j.Node, "i_word")
i_token = graph.get_or_create_index(neo4j.Node, "i_token")
labels = {"TOKEN"}
properties = {"name": "Ana"}
a_node = node(*labels, **properties)
c_node, = graph.create(a_node)
I'm getting the following error:
... py2neo/neo4j.py", line 237
... TypeError: Cannot cast node from (('TOKEN',), {'name':'Ana'})
Any ideas? many thanks for your time.
rgds,
Pedro
The node function in py2neo 1.6 does not have label support. You can only supply properties for creation and then later add labels. The alternative will be to use a Cypher expression such as:
CREATE n:TOKEN {name:'Ana'}
As a side note, bear in mind also that labels are generally be written in TitleCase rather than UPPER_CASE.

Adding a relationship to an index in neo4jclient

This might be real newbie question but please bear with me as I am new. I looked at this code sample in documentation.
graphClient
.Cypher
.Start(new {
n1 = "custom",
n2 = nodeRef,
n3 = Node.ByIndexLookup("indexName", "property", "value"),
n4 = Node.ByIndexQuery("indexName", "query"),
r1 = relRef,
moreRels = new[] { relRef, relRef2 },
r2 = Relationship.ByIndexLookup("indexName", "property", "value"),
r3 = Relationship.ByIndexQuery("indexName", "query"),
all = All.Nodes
});
In the example above I would like to get a relationship by IndexLookup. So I created a Relationship Index
_graphClient.CreateIndex("item_relationship_idx", new IndexConfiguration
{
Provider = IndexProvider.lucene,
Type = IndexType.exact
},
IndexFor.Relationship);
Question - How do I get a relationship created by _graphClient.CreateRelationship into an index. Most of the samples provided just show getting NodeReference into an Index. I am sure I am missing something obvious. Any help would be appreciated.
Update to Neo4jClient 1.0.0.568 or above and you'll find the (new) support for relationship indexing, consistent with how node indexing works.
(You should also look at Neo4j 2.0 and try and use the new indexing infrastructure though. No point writing new code against old approaches.)
Update to Neo4jClient 1.0.0.568 or above and you'll find the (new) support for relationship indexing, consistent with how node indexing works.
Does that mean I can use the Create method or do I still need the CreateRelationship method? I have Neo4jClient 1.0.0.590 but I don't find it that obvious.

Resources