Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.
10-31-2020 07:38 PM
So for the project that I am working on, I was working on desigined the address to be split into several nodes (for ex city node, state node, country node and zip node)
Now the country nodes themselves are unique so that part is simple. However you can have cities with the same name in the world but not at state level. Also zipcodes are unique but they are unique within a country. I have been trying to figure out how I could implement that design.
Here is what I though of so far when limited to just the zip code and country:
type Country {
name : String!
}
type ZIPCode {
zipId: ID! (This is handled by apoc.create.uuid)
zipcode: String!
country : Country @cypher(
statement:"""
MATCH (this)-[IN_COUNTRY]->(c:Country) RETURN c LIMIT 1
"""
)
}
Im not sure how to proceed from this point when dealing with creating a new zip code. Ideally I should merge if a zipcode exists within the same country but is that possible ? Or is this design flawed ?
The reason i have it set up as seperate nodes is so that I can query a specific node for addresses belong to nearby areas (For eg: Match all address - [havezip]->zipcode -[incountry]->country over searching address{zip: zip country:country} ) I expect this to be a very common type of query for my app so its what I want to optimize towards.
Solved! Go to Solution.
10-31-2020 07:51 PM
Having a clear understanding of the role of MERGE
will help you here. You don't really 'merge if it exists' as much as you just 'merge', which means 'make this pattern exist exactly like this, but don't create it again if it already does'. Worth having a read of the docs.
With that in mind, it's certainly valid to run:
MERGE (zc:ZIPCode {zipcode:'12345'})-[:IN_COUNTRY]->(c:Country {name:'xyz'})
and you will have exactly one instance of zipcode 12345
in country xyz
, whether it was already there or not.
You can add a uniqueness constraint to node properties such as zipcode
, but as far as I'm aware you cannot constrain a node's relationships in this way, so merge carefully.
10-31-2020 07:51 PM
Having a clear understanding of the role of MERGE
will help you here. You don't really 'merge if it exists' as much as you just 'merge', which means 'make this pattern exist exactly like this, but don't create it again if it already does'. Worth having a read of the docs.
With that in mind, it's certainly valid to run:
MERGE (zc:ZIPCode {zipcode:'12345'})-[:IN_COUNTRY]->(c:Country {name:'xyz'})
and you will have exactly one instance of zipcode 12345
in country xyz
, whether it was already there or not.
You can add a uniqueness constraint to node properties such as zipcode
, but as far as I'm aware you cannot constrain a node's relationships in this way, so merge carefully.
11-01-2020 02:15 AM
Ah Thanks a lot that helped. I read some more examples and that helped my understanding of merge. I do need to add the extra step of adding a match/merge on country so as not to recreate it but that seems trivial enough. Thanks a lot.
11-01-2020 12:36 PM
That's the power of merge - you probably don't need to do that. The statement:
MERGE (zc:ZIPCode {zipcode:'12345'})-[:IN_COUNTRY]->(c:Country {name:'xyz'})
will ensure there is a ZIPCode
node with that exact id, a Country
node with that exact name, and a relationship between them. MERGE
works against the entire pattern, not just one specific node/relationship.
11-02-2020 05:19 AM
Does that graphQL create uniqueness constraints on the Zipcode label in the graph to have a zipcode and country name?
Or does it open up the potential for Zipcode 1 being connected to multiple Country nodes via other data access vectors?
All the sessions of the conference are now available online