Real developer problem that gets solved by #graph. Today's thread: JSON document nesting
π§΅
so it's common to have data elements like a "food" with some related information (here, it's "nutrition information"). When using a document database you basically have two choices:
- Store the two documents separately and lookup the other when needed
- Store them together
Storing them together is great for efficient read operations. But it's bad for updates. If many foods share the same nutrition facts, and you need to update the facts, you have many updates to do to change one simple thing
because you duplicated data in sub-documents
what if you store them separately and then do lookups?
Well that makes updates easily, but then you pay the price on the reads
So to some extent, you're in a bit of a fix either way
note that we're in #graph territory here because fundamentally the question is about *the relationship between two things* and that's where graphs excel: in the relationship management. So how would a graph do this?
(:Food)-[:HAS]->(:NutritionFacts)
If you need to update nutrition facts, you only update one element (all foods are connected to it). And of course reads are fast too because optimizing for rel traversal is the whole point of a graph database. Best of both worlds
the schema (i.e. what properties we store about foods and nutrition facts) can independently evolve; unlike in a JSON database where they'll tend to be coupled either by ID or by structure.
Why does this work? Because relationships are "pre-materialized lookups"
when you write a relationship to a graph database, it's similar to doing a lookup or a join because you had to know what to connect.
The difference is that the cost is paid one time, up-front, and never again. Contrast with paying every time you query, or every time you update
the meta-pattern here is that when the problems you're struggling with are *about the relationships* then #graph will likely help and when the problems are about dealing with large numbers of homogeneous not necessarily connected individuals, then graph probably isn't the fit
β’ β’ β’
Missing some Tweet in this thread? You can try to
force a refresh
For some reason, some mutuals got me thinking about smoking
Memory: working as a teen, I knew a guy who was 100% sure that it was the glue in cigarette papers that caused cancer, not the tobacco. He smoked natural tobacco leaf-wrapped cigars, thought he was all good
at the shop where I worked, there was a 90-yr old guy who walked with a cane. Was the spitting image of William S. Burroughs. Every day, he came in and got his usual, 2 packs of Lucky Strikes unfiltered
when you're a teenage smoker yourself, a 90-yr old with a 2-pack a day Lucky Strikes habit is like a hero, but even then I knew he was more lucky than "right"
This only shows part of the picture; with recursive CTEs in #SQL I believe it is the case that:
- You can constrain max recursion, but not minimum without writing extra code
Contrast to cypher:
MATCH (e:Employee)-[:REPORTS_TO*3..5]->(:Employee)
recursive CTEs are a good example of "implementing a graph abstraction on top of something else". Namely the employee table represents a bunch of node instances; the managerID is a relationship, and the CTE implements a graph traversal.
Example thread on how to load #JSON into #Neo4j Aura -- working up from simple to more complex. Let's use the .@TheHackersNews public API to load a mini-feed of stories.
First: head endpoint with best stories, and simplest JSON load:
the apoc.load.json call always returns "value" with whatever came back. HackerNews is sending results, an array of post IDs.
We can extract out just the post IDs with a bit of extra cypher like this. Nice clean array of long values.
One step further; now we will UNWIND the array, turning the nested array into each individual item, and then build the URL we'll ask of HackerNews to get the detail of each story. This is how we build URLs one by one; we just take the story ID and concat it into a string URL