I am constructing a graph in Neo4j like this. First, I create the nodes with an array property. Then I check if any two nodes have common elements between the arrays (using apoc intersection call) and if so I create a relationship between the nodes.
For example, lets say, nodes N and M has arrays S = [A, B, C] and T = [A, B, D] as properties, respectively, then N and M will have a relationship r between them, since they share the common elements A, B .
Now, each of the array elements also has properties associated with them and I want to populate the edge with common elements together with their properties. That is, we have A.name, A.age, B.name, B.age associated with them. Note that A and B are variables themselves. That is, A could be Doctor X and B could be Doctor Y .
How do I annotate the edges with the variable name and their properties so that I can query the database using the variable name? I somehow need to preserve the association between elements and their properties within the edges as edge properties.
You can add properties to edges and query by them, but be aware that you can't use the regular indexes on relationship properties, but it is possible to add a full text search.
That said, at times I do use unindexed edge properties in queries, but always in combination with label and node property filters. Here is a very simple example (note: you can create both nodes and relationship with properties in one cypher command, but this is may be easier to follow)
// create node A
CREATE (:NODE {name:'A'});
// create node B
CREATE (:NODE {name:'B'});'
// check that they were created
MATCH (x :NODE {name:'A'})
MATCH (y :NODE {name:'B'})
RETURN x, y
// create relationship, and set value (using set instead of inline)
// (there are two ways to relationship properties, see reference below for inline style)
MATCH (x :NODE {name:'A'})
MATCH (y :NODE {name:'B'})
CREATE (x)-[r:KNOWS]->(y)
SET r.relationship='friends'
// query relationship property for value and return a path
MATCH t=(:NODE)-[r]-(:NODE)
WHERE r.relationship='friends'
RETURN t
// same query, but return nodes and relationship
MATCH (x:NODE)-[r]-(y:NODE)
WHERE r.relationship='friends'
RETURN x ,r, y
@Joel Thanks. Yes, I realize we can do that. This is not what I meant. Each element in the array has properties that need to be set and there is a variable number of them.
A note of clarification, Neo4j allows properties to be added adhoc to any node or relationship, they do not need to be the same, this is schema-less, so any given node/relationships can have any property, or not have it. Just be aware that you may want/need to check if a property exists, before checking if the property has a specific value, otherwise the query results may not be what you expect.
If you want to dynamically create a series of properties on the fly it seems likely you'll need to construct the CREATE/MERGE query on the fly as a string, then execute it. There is an APOC function that enables this, (if you aren't already writing code in a language like java, python)
There are many ways to unwind an array, in neo4j/cypher or outside, then add properties, since the property name is dynamic I think you will need to create cypher strings, then execute them, but there might be another clever way around it? (interested to know if there is)
@Joel again, thanks. Yes, I am creating relationships and their properties dynamically through apoc. What I am looking for is preserving an association between two properties without introducing any pseudo node or relationship.