Sample json:
{
"data": [
{
"file" : "1.txt",
"type" : "text"
},
{
"file" : "2.json",
"type" : "json"
},
{
"file" : "1.html",
"type" : "html"
}
]
}
I am trying to create 3 nodes with file and type as properties
I am using following query to create nodes in neo4j
WITH {json} AS document
UNWIND document.data AS data
FOREACH (node in data| CREATE(m:`member`) SET m = node )
I am getting following error when i use py2neo driver:
AttributeError: 'module' object has no attribute 'SyntaxError'
In your case either use UNWIND or FOREACH
WITH {json} AS document
UNWIND document.data AS data
CREATE(m:`member`) SET m = data
or
WITH {json} AS document
FOREACH (node in document.data | CREATE(m:`member`) SET m = node )
Query should be like -
WITH {json} AS document
FOREACH (node in document.data| CREATE(m:`memeber`) SET m = node )
Related
I'm looking for a query which can find all of the nodes which have properties that match a parameter which is an object. The properties of the node can be a superset (contain more properties than the filter)
e.g.
:param obj : { first : "first" }
CREATE (n:Test { first : "first", second : "second" });
CREATE (m:Test { first : "first" });
CREATE (f:Fail { first : "bad", second : "second" });
MATCH (c)
WHERE
PROPERTIES(c) = $obj
RETURN c;
n and m should be returned as they are matching on first : "first"
it is doable with apoc, basically by matching the obj with a submap of the properties, containing only the keys that are also present in obj
WITH { first : "first" } AS obj
MATCH (c)
WHERE apoc.map.submap(properties(c),keys(obj),[],false)= obj
RETURN c
I am trying to create a node only if the key exists in my json file. However, it is only able to create some nodes but not all
call apoc.load.json($url) yield value
unwind value as q
merge (report:Report {filename:q.filename})
ON CREATE SET report.title = q.title,
report.published_date = q.published_date
// HASHES
with report, value
unwind value.hashes as hashes_obj
with report, value, hashes_obj
where hashes_obj.sha1 is not null
merge (hash_sha1: Hash_sha1 {sha1: hashes_obj.sha1}) // I am able to create this node
merge (report)-[:contains]->(hash_sha1)
// I can't create this node
with report, value, hashes_obj, hash_sha1
where hashes_obj.md5 is not null
merge (hash_md5: Hash_md5 {md5: hashes_obj.md5})
Below is my json file
{
...
"hashes": [
{
"sha1": "c61b53b85c538dc46254c4f1da7717a29a3b27f3",
"file_name": "jsunpack.je",
"is_ssl": false
},
],
...
}
{
...
"hashes": [
{
"md5": "a90a329335fa0af64d8394b28e0f86c1",
"is_ssl": false
},
{
"md5": "07f4b663cc3bcb5899edba9eaf9cf4b5",
"is_ssl": false
},
{
"md5": "b751323586c5e36d1d644ab42888a100",
"is_ssl": false
},
{
"md5": "8ad9cb6b948bcf7f9211887e0cf6f02a",
"file_name": "lsass.exe",
"is_ssl": false
},
{
"md5": "be0cc8411c066eac246097045b73c282",
"file_name": "mshtml.dll",
"is_ssl": false
}
]
...
}
For some reason, I can only create the sha1 node but not the md5 node and I'm not sure why. Please help me out?
The WHERE hashes_obj.sha1 is not null test is eliminating all hashes_obj maps without the sha1 property. That means all the maps with the md5 property are eliminated.
This should work:
CALL apoc.load.json($url) YIELD value
UNWIND value AS q
MERGE (report:Report {filename:q.filename})
ON CREATE SET report.title = q.title,
report.published_date = q.published_date
// HASHES
WITH report, value, REDUCE(s = {sha1:[], md5:[]}, x IN value.hashes |
CASE
WHEN x.sha1 IS NOT NULL THEN {sha1: s.sha1 + x.sha1, md5: s.md5}
WHEN x.md5 IS NOT NULL THEN {sha1: s.sha1, md5: s.md5 + x.md5}
END
) AS todo
FOREACH(sha1 IN todo.sha1 |
MERGE (hash_sha1:Hash_sha1 {sha1: sha1})
MERGE (report)-[:contains]->(hash_sha1)
)
FOREACH(md5 IN todo.md5 |
MERGE (hash_md5:Hash_md5 {md5: md5})
)
I have a JSON in the next form:
{ "conditions": [ { "id": "123", "type": "a", entities: ["529", "454"] },
{ "id": "124", "type": "b", entities: ["530", "455"] }
]
}
I want to create relation ship between the Condition node with node A Entities or node B entities based on type attribute which can be A/B i Assuming that these entities already exists in neo4j.
I am trying something like the below cypher but that doesn't work.
WITH {json} as data
UNWIND data.conditions as condition
MATCH (c:Condition { conditionId: condition.id})
CASE c.type
WHEN 'a' THEN FOREACH (sid IN condition.entities |
MERGE (s:NodeA {nr_serverId:sid}) MERGE (s)-[:ATTACHED_TO]->(c)
)
WHEN 'b' THEN FOREACH (aid IN condition.entities |
MERGE (a:NodeB {nr_appId: aid}) MERGE (a)-[:ATTACHED_TO]->(c)
)
END;
Can anyone please help me with the correct way of doing this? Thank you.
Since at the moment there is no classical conditional statements in cypher, you can use the famous trick with foreach and case:
WITH {json} as data
UNWIND data.conditions as condition
MATCH (c:Condition { conditionId: condition.id})
FOREACH (ift in CASE WHEN c.type = 'a' THEN [1] ELSE [] END |
FOREACH (sid IN condition.entities |
MERGE (s:NodeA {nr_serverId:sid}) MERGE (s)-[:ATTACHED_TO]->(c)
)
)
FOREACH (ift in CASE WHEN c.type = 'b' THEN [1] ELSE [] END |
FOREACH (aid IN condition.entities |
MERGE (a:NodeB {nr_appId: aid}) MERGE (a)-[:ATTACHED_TO]->(c)
)
)
APOC Procedures just updated with support for conditional cypher execution. You'll need version 3.1.3.7 or greater (if using Neo4j 3.1.x), or version 3.2.0.3 or greater (if using Neo4j 3.2.x).
Here's an example of using these new procedures to execute your query:
WITH {json} as data
UNWIND data.conditions as condition
MATCH (c:Condition { conditionId: condition.id})
CALL apoc.do.case([
c.type = 'a',
"FOREACH (sid IN condition.entities |
MERGE (s:NodeA {nr_serverId:sid}) MERGE (s)-[:ATTACHED_TO]->(c))",
c.type = 'b',
"FOREACH (aid IN condition.entities |
MERGE (a:NodeB {nr_appId: aid}) MERGE (a)-[:ATTACHED_TO]->(c))"
], '', {condition:condition, c:c}) YIELD value
I am trying to create multiple nodes in Neo4j using Cypher by passing properties as parameters as part of an UNWIND function, but I keep receiving the error Type mismatch: expected Collection<T> but was Map.
This happens even when using the following example from the Neo4j documentation (link):
UNWIND {
props : [ {
name : "Andres",
position : "Developer"
}, {
name : "Michael",
position : "Developer"
} ]
} AS map
CREATE (n)
SET n = map
Can anyone point out what I am doing wrong here?
Note, the example above is not exactly as in the Neo4j documentation. Their example wraps the property names in double quotes, but this causes my instance of Neo4j to throw the errorInvalid input '"': expected whitespace...)
UNWIND is expecting a collection, not a map as you're currently passing in, try this instead (just remove the wrapping curly braces and prop top level field):
UNWIND [ {
name : "Andres",
position : "Developer"
}, {
name : "Michael",
position : "Developer"
} ] AS map
CREATE (n)
SET n = map
Chris's answer is of course the correct one, but here's why your solution doesn't work when you're following the documentation: you're not copying the documentation.
The documentation shows the use of a named parameter:
UNWIND { props } AS map
CREATE (n)
SET n = map
with props passed in the map of parameters, which would look like:
{
"props" : [ {
"name" : "Andres",
"position" : "Developer"
}, {
"name" : "Michael",
"position" : "Developer"
} ]
}
if you displayed the map as JSON. It means the {props} placeholder will be replaced by the value for the props key. Which is exactly what Chris did.
Here's what the Java code would look like:
GraphDatabaseService db = /* init */;
Map<String, Object> andres = new HashMap<>();
andres.put("name", "Andres");
andres.put("position", "Developer");
Map<String, Object> michael = new HashMap<>();
michael.put("name", "Michael");
michael.put("position", "Developer");
Map<String, Object> params = new HashMap<>();
params.put("props", Arrays.asList(andres, michael));
try (Transaction tx = db.beginTx()) {
db.execute("UNWIND {props} AS map CREATE (n) SET n = map", params);
tx.success();
}
I am using json to create nodes in noe4j
I have written a small c++ prog to do so using curl and json
Now i have to create around 10000 nodes in neo4j with properties having name and value.
For that i am using props in json with the query as
{
"params" : {
"props" : {
[{name : "a", value : 1}, {name : "b", value : 2}......so on]
]
}
},
"query" : "CREATE (n:Router { props }) RETURN n"
}
the question is I just want to create that nodes with unique names. If a node is already present with the name as in json props I do not want to create it.
How to write a query for these types of request in neo4j
Change your query to the following:
{
"params" : {
"props" : {
[{name : "a", value : 1}, {name : "b", value : 2}......so on]
]
}
},
"query" : "FOREACH (router in {props} | MERGE (n:Router {name: router.name}) ON CREATE SET n = router)"
}
Basically it iterate the items in your list, check for name property if it exist and it case it save a new node