0

I'm using py2neo cypher to load relationship between nodes. I would like to use a json object as this relationship, so I can query it later. Here is my cypher query:

 MATCH (a:OntologyNode),(b:OntologyNode) 
 WHERE a.cid = 'abcat1' 
 AND b.cid = 'abcat2' 
 CREATE (a)-[r:{'operand2': 'Product_Weight', 'operand1': 'Maximum_Weight', 'operator': '>='}]->(b)

Here is my error:

 InvalidSyntax: Invalid input '{': expected whitespace or a rel type name (line 1, column 111 (offset: 110))

I appears it doesn't like the '{', but is there a way around this? The reason I'd like this json as a relationship, is the ability to query it.

jKraut
  • 2,325
  • 6
  • 35
  • 48

2 Answers2

0

You can add the key/value pairs of the JSON as attributes on the relationship

MATCH (a:OntologyNode),(b:OntologyNode) 
WHERE a.cid = 'abcat1' 
AND b.cid = 'abcat2' 
CREATE (a)-[r:REL {operand2: 'Product_Weight', operand1: 'Maximum_Weight', operator: '>='}]->(b)

Then you could query it like this

MATCH (:OntologyNode)-[rel:REL]->(:OntologyNode) 
WHERE rel.operand2 = 'Product_Weight'
AND rel.operand1 = 'Maximum_Weight'
AND rel.operator = '>='

If you really wanted to use the actual JSON as the relationship then you could backtick the JSON string like this instead.

MATCH (a:OntologyNode),(b:OntologyNode) 
WHERE a.cid = 'abcat1' 
AND b.cid = 'abcat2' 
CREATE (a)-[r:`{operand2: 'Product_Weight', operand1: 'Maximum_Weight', operator: '>='}`]->(b)

If you wanted to combine the two, you could always store the JSON in another attribute on the relationship.

...
create (a)-[r:REL]->(b)
set r.operand2 = 'Product_Weight'
, r.operand1 = 'Maximum_Weight'
, r.operator = '>='
, r.json = "{operand2: 'Product_Weight', operand1: 'Maximum_Weight', operator: '>='}"
Dave Bennett
  • 10,996
  • 3
  • 30
  • 41
  • I really like the first approach. From what I can tell, you just added the "REL" in from the json. However, when I do that, I still get the error. – jKraut Apr 09 '16 at 18:03
  • Yes, I added `REL` is the relationship type. And I also unquoted the keys in the JSON: operand2, operand1 and operator. – Dave Bennett Apr 09 '16 at 18:39
  • The only issue with removing the quoting of keys is then it's not valid JSON. Otherwise it would work great. Any thoughts on how to fix that? – jKraut Apr 10 '16 at 01:24
  • That is because the JSON in that example is the format that Neo4j cypher parser expects. It consumes the JSON but actually stored the key/value pairs as attributes of the relationship object. You could always add the raw JSON as an additional attribute on the relationship. I updated the answer to include that as another option. – Dave Bennett Apr 10 '16 at 01:52
  • I still get the error when reading in using py2neo and json file. One reason I can tell is it's always keeping the keys in quotes. Using the set then json as an additional attribute also throws an error. – jKraut Apr 11 '16 at 01:46
  • I only tested the cypher out in the browser; I have not tried it in py2neo. – Dave Bennett Apr 11 '16 at 13:21
0

I am unclear what you mean by "I would like to use a json object as this relationship". A relationship is defined by Neo4j as a stored connection between two nodes with a textual type name and an optional map/dictionary of properties.

Please note also that JSON is merely a notation and not a type system. Furthermore, Cypher itself does not consume or produce JSON.

The literal map notation used by Cypher is similar to but not compatible with JSON. Property keys are generally unquoted except when they contain special characters, when backticks are used. Double quotes are not supported. Property keys should be considered identifiers, not strings.

You also say "the reason I'd like this json as a relationship, is the ability to query it". Cypher contains no JSON query functionality although you can of course query properties on a relationship.

If what you want is a relationship that contains properties, then you will need to give your relationship a type name and use Cypher map notation rather than JSON notation. Something like:

MATCH (a:OntologyNode),(b:OntologyNode) 
WHERE a.cid = 'abcat1' 
AND b.cid = 'abcat2' 
CREATE (a)-[r:RELATES_TO {operand2: 'Product_Weight', 
                          operand1: 'Maximum_Weight', operator: '>='}]->(b)

Obviously replace RELATES_TO with a relationship name appropriate for your domain.

Nigel Small
  • 4,475
  • 1
  • 17
  • 15