1 person, 1 place and dates object alignment in a Cypher

Help, I'm working on a personal project from my time in the military to assist me in reinforcing cypher use.

Problem Set
List of people from my specialty/community by name
List of Locations (military installations) that we can be stationed.
Years that the individual was there.

So: Charlie - stationed at Ft Campbell - from 1992->1998

I tried this:
MATCH (e:person {name:'charlie'}) MATCH(c:location {name:'Ft Campbell'}) MERGE(e)-[rel:ASSIGNED_1992]->(c);
MATCH (e:person {name:'charlie'}) MATCH(c:location {name:'Ft Campbell'}) MERGE(e)-[rel:ASSIGNED_1993]->(c);

But this just "feels" wrong programmatically, and how would I search on it to align everyone that was at X location during a specific year?

End state : The search I want to do is : At THIS BASE during THIS YEAR, WHO else was there with me? As is in civilian life, some folks spike out as being memorable but others were "just there" and no-one seems to remember them.

I'm probably overthinking this and the answer is stupid obvious.
Any assistance in pointing out the obvious would be appreciated.

You can find all the people at Ft Campbell during 1992 with the following query:

match(p:person)-[:ASSIGNED_1992]->(:location {name:'Ft Campbell'})
return p

You will need to create a new relationship of the person for each year they were stationed at the same location.

You can use the following query to look for people stationed at the Ft Campbell location during 1992 or 1993

match(p:person)-[:ASSIGNED_1992|ASSIGNED_1993]->(:location {name:'Ft Campbell'})
return p

Gotcha. So I was on the right track. It just felt "in-elegant" to do it that way. Thanks for the assist. I was burning calories trying to find a better mouse trap.

Well, there may be other ways to handle it as well. It depends on your requirements which is best. I was commenting that you can derive the information you want from this model.

One limitation is that you can not determine the actual period an individual was assigned to a location. You would need to store the start and end dates of each assignment. It is also difficult to use node labels and relationships types that vary like this, as they can not be passed as parameters. I have seen data models where it made sense.


You can try putting properties on the relations. Then you could use

MATCH (e:person {name:'Charlie'})
MATCH(c:location {name:'Ft Campbell'})
MERGE(e)-[rel:ASSIGNED {start_year:1992, end_year:1998}]->(c);

Then if you want to check if Charlie was assinged to FT Campbell in 1994, you could use a query something like:
MATCH (e:person {name:'Charlie'}) -[rel:ASSIGNED]-(c:location {name:'Ft Campbell'})
where rel.start_year <= 1994 <= rel.end_year

There are many more improvements you could do if you find this solution good for you.

Warm Regards,

Outstanding! I love how Neo4j and Cypher are so flexible. I have been working IT since computers were the size of buildings. Todays databases and the methods to actually make them work are so much better and the knowledge base is so much wider. Google search vs reading a 9000 page instruction manual.

1 Like