Build Neo4j Applications With Node.js
Links & Resources
Click to expand the full transcript
Captions provided by White Coat Captioning (https://whitecoatcaptioning.com/). Communication Access Realtime Translation (CART) is provided in order to facilitate communication accessibility and may not be a totally verbatim record of the proceedings.
JASON: Hello, everyone, and welcome to another episode of "Learn With Jason."
Today on the show, we have Adam Cowley.
Adam, how are you doing?
ADAM: Good, yeah, yeah, happy to be here.
JASON: Happy to have you on the show.
Appreciate you taking the time.
I am really excited to dig into what we're going to cover today, but before we do that,
I'd love to hear a bit about you.
For folks who aren't familiar, can you give us a bit of a background?
ADAM: My name is Adam.
I'm a developer relations team at Neo4j.
I look at the advocacy side of things.
And developer education, basically.
So, I describe myself as a full-stack developer.
I've been working on the web for about 20 years now, since layouts were in tables, and
you did little GIFs with rounded edges to create layouts and things like that.
In the past, I've been a freelance web developer for a few years, and a consultant.
I've been at Neo4j for about four years now.
So, for two years of that I was a professional sources consultant, and I moved over to dev
rel about two years ago now.
JASON: Nice, nice.
And, so, I'm always really curious about whenever I hear people talk about Neo4j, I'm intrigued,
and also have no idea even where to start thinking about it.
So, if people listening are like me, may have heard the name, but aren't really clear on
what it is, do you maybe want to give us the high-level overview of what Neo4j is?
ADAM: Yeah, sure.
So, ignore the name.
The "j," it originally standed for Java, but ignore that.
So, high level, it's a graph database, which is a bit of a paradigm shift for most people,
you know, full-stack developers or back-end developers, are used to storing data.
But, basically, when I talk about graphs, I don't talk about chart js or something like
I'm talking about graph theory and graph structures.
Basically, nodes to represent data, and then relationships to represent the connections
And, so, graph databases, I feel like graph databases have been sort of conflated with
GraphQL, which is a spec, but they are not the same thing, right?
ADAM: Yeah, yeah, correct.
GraphQL is a way of querying a graph structure space.
I'm not 100% up on what GraphQL is, personally, but from what I understand, it's a way of,
I guess, something created by Facebook to Google their social graph.
So, if you think of the social graph structure, you've got people that connect it in different
So, you may be a friend, make a profile, those sort of connections.
So, GraphQL is a spec for querying a graph in a certain format.
Yeah, so, there are two ways to query a database.
So, you would use a language called Cipher, which is a pattern matching language for matching
patterns in the graph.
But, yeah, it's completely separate from GraphQL and the GraphQL spec, really.
Yeah, so, I guess, yeah, I guess in most cases you'd be, you know, you'd use a service like
Fauna for GraphQL.
Not quite sure what they use under the hood.
May even be like some sort of wrap or something on top of Postgres, which is how Neo4j started
in the first place, quite interestingly, ten years or so.
But the founders kind of found out that didn't really scale.
I guess it's a problem I've seen when I tried to use GraphQL with other databases in the
past, is that you have your mutations, then go and fetch something that would come back,
and you'd have, like for nesting, you have to fetch other items from other places.
In theory, it sounds great that you would have this one kind of contract with a front
end, where you define all of these nested objects, and you just bring back what you
Actually, depending how you do it, it can be difficult to find things from different
places, slow and costly, as well.
I want to dig into that a little bit, because I'm always interested in this, because one
of the things that I find fascinating about just development in general is that the more
I learn, the more I realize that there's no such thing as a right answer.
You know, there's no complete solution or silver bullet or anything like that.
So, when we're talking about a graph database -- I guess what is the main use case, or when
is the right time to start reaching for a graph database?
Where is it going to shine?
ADAM: I guess, so, from an abstract point of view, you're kind of looking for the best
tool for the best job.
ADAM: You kind of use Neo4j, where you have a highly connected data set, like a social
graph is a good example of that, because you have people that connected by certain degrees
and certain weights to other things.
Think, for example, like routing of packages across Europe, if you sent a package across
Europe, the optimal path has been routed by graph database.
Basically, you would use a graph database in a time where you need to query a highly
connected data set in realtime, basically.
ADAM: So, yeah, so the golden rule is if you got three or more joints in your relational
database, you should be looking at graph database.
Slow down from there.
JASON: I feel like I'm starting to really appreciate heuristics like that.
Because as I have been just expanding in my career and building more and more things,
what I've learned is I can build just about anything with just about anything, right?
Like it's always theoretically possible to get something done using whatever tool is
You know, you can skip all the tools and build the whole thing with just HTML, and CSS, and
But the challenge then becomes, you know, you have, like, you're inventing a lot of
frameworks along the way.
So, as I've been gaining expertise, I guess, one of the things I've really learned to live
by is heuristics like that.
So, that is a good, you know, when is it the right time to think about a graph database?
If you have three or more joins in your relational database.
And, so, can you clarify, when you say a join, can you give an example of a situation where
you have three or more joins?
So, I guess the example could be that you have, like, you run an online shop.
You have a user's table, an orders table, and a products table.
So, in that case, you kind of have to do some sort of magic, because you can't do a relationship
between an order and a product, for example.
So, you end up leading an order line table, which is -- so, it's kind of like an unmatched
modeling, and it takes a lot in the main layer of your application to get that thing to work.
And there's, yeah, lots of things you have to go around, or lots of hoops you have to
jump through to sort that out.
Whereas in Neo4j, you'd model that as a node for the order, and then you'd have a direct
relationship to the product.
And then you could have on the relationship a set properties to say, you know, what was
the price when they bought it, did they use discount codes, you know, the quantity, things
And then, so, if you take a step back from that, as well, when you look at querying across
tables in a relational database, or even like in a Neo4j database, what happens is when
you query that data, the joins are calculated at read time.
Say you have between two tables, you would find the record that you want in the table,
same example the order table, and then you would find the order, and then you would join
the order lines.
So, I mean, the more successful your business is, and the more things you sell on your shop,
the slower that's going to get, because the index for the foreign key that you use on
the join is going to grow over time.
ADAM: The more your shop sells, the more in that table, the longer that query takes.
So, with Neo4j and databases in general, they use a concept called index free adjacency.
So, when you save data to a graph database, the relationship between any two entities,
or any two nodes, is stored at read time.
So -- sorry, at write time.
So, every node is aware of every relationship coming into and going out of it.
So, you don't have to compute the joins at read time.
You can basically chase memory to find where that node is on the other end of the relationship.
And that's what makes it quick, because the speed of the query is not proportional to
the size of the database and table, but only the size of the data that you touch.
If you have, say, for example, 5 billion people in a social graph, and you want to query my
friends, I don't have to look through the whole database to find my friends.
I can just go directly through those relationships.
JASON: So, that is really interesting.
Because it's sort of -- it's putting what I'm trying to accomplish with something like
a social media app as the main focus of the database that we're designing.
And I think that's a really good shout to, like, as a programmer, my goal should be to
choose the tool that solves the use case in the most effective way.
And by looking at my data, you know, I'm going to build an app.
That app is going to have a ton of relationships for discreet types of objects, you know, e-commerce
shop, a social media thing, you know, even looking at a -- just a blog.
You've got authors, you've got posts, you've got comments, maybe you've got editors, maybe
you've got categories, tags.
Each of those things now starts to make different relationships, right.
So if you see lots and lots of relationships, then knowing that you're designing something
to be multi-relational like that, where you do have lots and lots of different ways the
data connects to itself, you can say, oh, well, I know that if this -- you know, basically
for convenience up front, because I want to be able to just say, yeah, give me a post
and the author of that post, comments for the post, categories, and related posts based
on the categories.
In a graph database I say that and it works.
In a relational database, I'm saying, give me all the posts, and now I have an idea of
Another query, get me the author of this post by ID.
Get me the comments for this post by ID, and maybe those comments come with their own relations
of who the author is, or things like that.
And you suddenly have this really complex way of sourcing and aggregating data.
But, you know, on the flip side of that coin, if I have non-relational data, like I have
something where it's very clearly going to be one entity with maybe one relationship,
then maybe it's not worth thinking about the graph relationships and stuff.
I can be pragmatic about the way these things grow.
And, you know, it's also -- yeah, just feels like the sort of thing where it's not necessarily
a choice about what the best tool is for the raw merits of the tool, but rather for fitness
JASON: And that's actually one of the reasons that people talk about, outside of Neo4j when
you talk about graphs, you'll see people be absolutist about everything should be GraphQL,
everything should be rest, or however they want to phrase that.
I find myself in the camp, well, I use them both, based on which one is easier for me
to scale, or easier to work with based on the kind of data that I have.
And, so, you're putting into words some of the decisions that I've been making just kind
of based on convenience.
And kind of extrapolating that out.
Because I'm not doing things for millions of users, where my database indices would
None of the apps I build are that big, but they could be.
If one of them runs away, I accidentally create the next Wordle, it would be great to support
that type of attention.
So, as you kind of start looking at this, what have you seen, you know, I feel like
the default answer is always going to be a social media, or you gave another one, which
is good, which is e-commerce.
What are some other common use cases, where somebody is really going to see the benefits
of a graph?
ADAM: So, I guess there's this misconception maybe in the tech community that graphs are
like a niche thing.
Like you say, you always use the right tool for the job, but, I mean, graphs can handle
the same loads that relational database or another database can use.
I said a couple days ago, graphs are everywhere.
So, it's kind of like the unofficial motto of Neo4j, you know, graphs are everywhere,
and you start to see them.
So, I first found Neo4j about eight years ago, I guess.
And since then, I've been seeing graphs everywhere and connections everywhere.
So, the common use cases I used to work on in the field were things like real-time recommendations.
So, you know, in realtime, you know, show me -- even people who bought a product, what
else did they buy?
ADAM: It's not that complicated, but it's a slow one when you have a huge database and
a lot of customers.
That's a good one, because you're kind of hopping over a small part of the network any
Other common use cases, I work on things like fraud detections.
Typically, fraud is carried out by rings of people.
So, like -- they have like -- I think it's called the "cash for crash scandal" in the
UK a few years ago.
One person would crash their car and get the insurance money.
And they'd end up crashing their car into somebody else, there would be this chain of
And that's, you know, an easy way to find kind of this chain of people in a graph database.
It would be really hard to write like a store procedure in a relational database to think
ADAM: Or, like, credit card fraud and things like that.
People using the same details in -- for their application.
So, sharing phone numbers, sharing addresses, things like that, are kind of red flags.
You know, if you think of networks, for example, that's like a common thing, the connection
between switches or servers is the most important thing.
So, you'd use a graph for that.
ADAM: Literally, could be sort of applied anywhere, really.
So, one of the big things that Neo4j has been used for, one of the big public stories, has
been things like, you know, the Panama Papers and the Paradise Papers, there's one on Buzzfeed
about Trump, I can't remember the name of it.
Taking the leaks, turning that unstructured data into structured data, and looking at
the connections between people.
Then you can kind of see the connections between the certain former U.S. president and a head
of state on the other side of the globe, things like that.
ADAM: Flow of money, things like that, and how things go through.
I spent some time with a company looking at Bitcoin and blockchain.
Blockchain is a graph, because you have different transactions loaded up.
JASON: Sure, sure.
ADAM: But interesting thing, going back to fraud, what is the flow of money between these
NFTs, how will the NFTs move through a network of people?
These are all things that can be solved easily, with a graph database and one line that could
be thousands of lines of Java.
Or C-plus to find the answer.
No, that's kind of fascinating.
And it reminds me of another kind of growing niche area of popularity for graphs, which
is just person notetaking.
If you use a tool like Obsidian, or there's Foam for VSCode, there's Rome Research, and
these personal databases, where as you write, you can kind of categorize a word, double
bracket or something, that makes a node, things like that.
And you end up over time getting this map of the way your brain has been working, where
you can see, oh, I talked about this concept many times.
And then you can go back and sort of clean those up and add aliases and sort of things
to really get this clear idea of the way relationships are forming in your head between different
types of data that is -- I mean, I've never seen anything that serendipitously surfaces
relationships like that.
Prior to this, you know, you would have to do something like go back and re-read all
of your notes, or you would have to do a very dedicated project to surface the common things.
And to be completely honest, most of us aren't going to do that, right, we're not going to
take the time to go back, dig through this stuff, figure out how it all works.
But with a graph database, using our notes as the input for a graph, we suddenly start
to draw these connections.
I just did this the other day, where I was looking at my work-in-progress blog post.
I've got a couple dozen things I started writing, didn't get all the way through it, and I went
Turns out a bunch were on the same theme, so I was able to pull that together in one
post and publish the redux of the three or four posts on a theme.
That sort of thing hadn't entered my realm of consciousness until you just said this,
that is, in fact, a graph database that's had a measurable impact on the way I'm able
to think, and the way I'm able to parse information.
So, that is really interesting to think about, because I couldn't have done that with a relational
database, right, I couldn't have done that with a -- you know, you can't structure your
And, so, what I'm hearing in taking all of what you're saying in maybe an extrapolative
direction here, graph databases are really good for finding things that you weren't looking
for in your data.
Like you said with fraud or like I said with notes.
Do you feel like that is a fair characterization?
ADAM: Yeah, yeah, definitely.
So, I mean, I hate the word, but keyword is insights.
Finding insights in your data.
I know that's kind of a sales-y thing, maybe a bit of a cliche.
Yeah, makes sense.
What can I see within three degrees of this particular piece of data that I have, you
know, how's it connected to other things.
And it's something you can visualize really quickly.
And understand it quickly, as well.
Okay, so, now my brain is spinning.
I kind of want to see this in action.
I think this is a good point for us to switch over.
Let's go take a look at how we can actually use a graph database.
So, I'm going to switch us over into the pair programming mode.
I just realized I made a small -- maybe this will work, let's just find out.
I'm using a new system.
I switched over to a video platform called Ping.
Oh, and it, works.
I did an okay job.
But I'm in the wrong mode.
Hold on one second while I switch this and fix it.
This is the right one, probably.
There it is.
All right, everyone.
So, first and foremost, like we do every episode, I want to send a huge thanks to our live captioning.
We've got Ashly here with us today from White Coat Captioning.
That is all available on the home page of the site, learnwithJason.dev.
While you're there, check out our sponsors, Netlify all making this accessible, keeping
the lights on, keeping us operating here.
We are talking today to Adam, which I had your -- let me go to your -- there we go.
Adam on Twitter, you can go and follow here.
And this is an anti-Java balance.
ADAM: Not a lot about Java, my friend.
JASON: That's good.
I know zero Java.
This would be a very confusing episode for all of us, if we were going to go straight
Yeah, make sure you give Adam a follow.
And we are talking today about Neo4j.
And you can find more information about that here.
So, that is about the extent of what I know about Neo4j.
I did, to save some time, sign up for a Sandbox.
And the way I did this, did this get started, I use the Sandbox, used my Google email, all
Now I've landed here.
I'm through, what's the first thing we should do?
ADAM: All right, so, first thing we should do is create an example data set.
There are two ways you can get started for free on Neo4j.
If you know what you're doing and kind of want to play around, you can use Neo4j Aura,
like our free cloud offering.
You can have 50,000 nodes, 175,000 relationships free of charge, forever.
But if you want to play around, there's the Neo4j sandbox you can use.
The Neo4j sandbox is tiny instances, barely any RAM, but they work with the datasets.
JASON: Oh, should I have signed up for the aura, if we're going to share this as an example?
ADAM: What we do, we can -- everyone can replicate by creating a new sandbox.
Should be fine.
New options there, interesting ones there.
If you scroll down to recommendations.
JASON: Oh, sorry.
I was looking for a headline.
ADAM: Click create in the bottom left.
This fires up one of the sample data sets.
These last for three days, and you can extend if you want to play around.
If you click open, it will open up the data set in the browser.
The like a visual querying tool, essentially.
You can explore the data from here, write cipher queries, which you'll view today.
You can sort of look for the graph.
If you want toe look in broader scale, there's a tool called blue, which allows you to visualize
So, if you go back to the sandbox.
JASON: Oh, bloom.
ADAM: Bloom, yeah.
JASON: Share this with everybody, in case you want to peek at this later.
ADAM: When you create one of these sandboxes, I'll give you the abridged version.
You can click through.
If you click on the top left-hand corner, there's a database icon, click on that.
Like I said earlier, a graph is a combination of nodes, set nodes, connected together via
So, you can see from there you've got 26,000 nodes in there.
Every node can have 0, 1 labels.
So it's a way of kinda categorizing and tagging the data
So if you click on a person
JASON: This one?
ADAM: Yeah, so that brings up the first 25—
This is the point I call the graph epiphany, where you're going to start to get excited.
You see from that guy there, that you've got on, that is if you hover over it.
JASON: This one?
Click, at the bottom of the result window, there's act or in person.
Those are the two labels.
At the right, there's a carrot icon.
So, these are the properties that are against that node.
So, what you can do, search for all people, regardless who they are, or search for actors,
or you can search for directors.
So, immediately, you can start to slim down your dataset.
Do you recognize any of those actors there?
JASON: Let's see if I do.
It's quite an old data set.
I'm not very good at --
ADAM: Favorite actor from the '90s.
JASON: What do you think, chat, '90s, early 2000s.
I'm leaning Brendan Fraser.
Always a fan favorite.
If you click on that match.
This is the query, so there's lots of references to things that sound a lot like matrix.
The founder of Neo4j is a big fan of the Matrix, and it shows.
JASON: Oh, chat, did you all just get it?
Neo, cipher, a light bulb just went off.
ADAM: I don't know if it's an acronym, but Neo4j, Neo is network engine and objects.
Which came first, I'll let you decide.
This is a proprietary language that allows you to basically search through match patterns
in the database and return them back.
This is the main thing for me, when I started using Neo4j eight years ago, Cipher was just
lunched, and this is the thing that got me excited.
Compared to SQL, this is exciting.
See where you have end person in Brachts, what you do is draw a circle for a node.
You're saying, after the colon is the label.
Then you're giving it a variable of n.
So, put dashes either side, and then put the type after a colon.
So, yeah, like a really nice way to query.
Just before the bracket, if you put the -- closed bracket, sorry.
If you put a space -- so open curly braces.
JASON: Get some curly boys in there.
ADAM: Sorry, the JSON ones.
JASON: Curly, got it.
ADAM: Name, colon, then in speech marks, actor of your choice.
JASON: We decided Nicolas Cage -- actually, Keanu Reeves.
ADAM: Cool, hit enter on that.
Or press play.
That gives you Keanu Reeves.
So, double click on that and see the movies that Keanu Reeves has acted in.
ADAM: It's quite a small data set.
So, you can see you've now got a set of nodes that are connected by arrows.
Yeah, arrows and a type.
So, if you click on that match n:person again, after the closed brackets.
Do a dash.
So, open square bracket.
Do acted in, so you can click on -- yes, like that one.
So, more than arrow, this is a relationship in the outgoing direction from Keanu Reeves.
ADAM: Draw another node.
Give that an alias.
I guess this would be like "m," for the movie.
JASON: I understand, n is a variable name, not a shorthand for node.
JASON: Got it, got it.
ADAM: Then you can do colon movie.
So, acted in a movie.
So, upper case "M," movie.
JASON: Like this?
So, that is matching a pattern in the database of a person node with an outgoing relationship
to a movie.
ADAM: So, in order to return it, you first
JASON: Oh, I need -- do I need to change this to M?
ADAM: Not colon, comma.
So, you're kind of listing what you want to return from that pattern above.
JASON: Got ya, I understand.
ADAM: That gives you that data.
So, now what we have done now, instead of having to click this to get the relationship,
I'm able to kind of precede this visualizer with -- by drawing this relationship.
And this is really like -- when you said it's kind of like ASCII art, not going to lie,
I was immediately like -- uh-oh.
But this is really intuitive.
Now that I know.
Okay, this is a node, and we're saying along this edge or relationship is acted in to a
Yeah, this makes sense.
Is it possible if I don't add one of these, I could just say give me all the movies related
to Keanu Reeves by any relationship by just putting in an arrow?
JASON: That's a good sign this is intuitive, I just guessed that, and it would have worked.
So, you could kind of say, you know, give me everything that is within three degrees
of Keanu Reeves.
I guess could be quite an interesting thing.
So, if you remove the ":acted in," and then do -- so, if you do "star 1..3," and remove
the arrow just before the movie.
Leave the dash in, sorry.
JASON: Oh, leave the dash in.
ADAM: So, this is saying, give me every -- well, this would be every movie within 1 to 3 degrees
of Keanu Reeves.
So, if you hit enter on that or "play," run the query.
It should connect all together.
JASON: Oh, interesting, okay.
ADAM: Yeah, so, this is giving you -- sorry.
If you click on the "n:Person" again.
Sorry, yeah, the query.
If before the "n" you do "P =," and then return "P."
Now instead of matching individual nodes inside the database, you're actually matching a path
So, you could say give me the shortest path between two actors.
So, this is everything from Keanu Reeves, and then going out to somebody else.
So, the limit is only 25.
So, it's not a huge dataset.
So, actually, if you do just star 3, rather than 1 to 3, it would give you paths, first
link, second, third.
Let me try to explain back what I'm seeing here, to make sure I'm understanding what
So, we said match the path of anything, any movie, within three degrees of Keanu Reeves.
JASON: And what the path did, okay, Keanu Reeves is within three degrees of "Thriller,"
and everything being returned is connected to "Thriller," so we can say that's the path
to Keanu Reeves, is through "Thriller."
ADAM: So, thriller is the genre.
So, for example, from Keanu Reeves into is it Johnny Mnemonic?
ADAM: Sorry, text is small for me.
Then goes from thriller, then to the movies in thriller.
JASON: So, it basically found a common node to connect everything through?
ADAM: So, what you could do is say from Keanu Reeves and do it -- so, if you do star 5 rather
than 1 to 3.
JASON: Star 5.
ADAM: Instead of movie, if you do person.
This will find people that have acted in movies, that have acted in movies of people that acted
with Keanu Reeves, if that makes sense.
JASON: Got it, got it.
So, we're basically playing six degrees of Kevin Bacon but with a graph database.
ADAM: Exactly, yeah.
Not a good sign it's -- so, what happens is when you use Bloom, Bloom is written in Canvas,
with Canvas, I should say.
You can do larger visualizations.
I think what's happened here, because the visualization is so big, this is SVG, it struggles.
JASON: Got ya.
Cool that you can blow this up, too.
I'm going to take advantage of this, so we can see the -- oh, retry your operation.
Did we make it too big?
If we change it to three, I guess.
Or if you do limit, limit one.
JASON: You want me to decrease the limit, as well?
ADAM: Yeah, yeah, that should help out.
Like I said, these are really small instances.
JASON: No changes, no records.
ADAM: Sorry, it would be two.
Two degrees of separation there.
JASON: Oh, yeah.
Okay, Keanu Reeves, acted in "The Gift" with Katie Holmes.
ADAM: So, imagine that was star 5 and you had loads of nodes there.
JASON: How much time do you lose to doing exactly this when you have this open?
ADAM: In the early days, a lot of time.
JASON: I would say, this would be solidly 50% of what I spent my time doing if I worked
ADAM: Definitely a lot of double clicking and expanding things out.
That's how you learn about a dataset, how's this related to that?
JASON: This is great.
This is magical, too, because it really does show, okay, how many people have acted with
Keanu Reeves, and if I lift this limit to, say, 10 -- we'll start to see quite a bit
of, you know, here's one particular movie.
And we can see -- this is just -- yeah, I love this.
I can see if I'm building a recommendation database or something, if I notice that, say,
Marissa Tome is in a lot of movies with Keanu Reeves, I like the ones I've seen, I can recommend
that, or look for other commonalities that are going to start showing up by nature of
surfacing this data.
You know, we already found kind of serendipitously, we didn't talk about genre, but it found thriller
and said, oh, a lot of these movies are related to Keanu Reeves via being a thriller.
That's sort of a random chance that happened, and not all of Keanu Reeves are thrillers,
but if I was into thrillers, I could say show me all the movies related to Keanu Reeves
that are thrillers and filter that way.
So, my brain is kind of spinning with ways this could be really useful, and useful in
ways that would be really difficult if I had to manually write queries to make it happen.
ADAM: Absolutely, yeah.
Yeah, yeah, imagine if you were saying find me any actor that's within two and ten degrees
after particular actor at a certain time.
If you were writing an SQL query, left joins, be coalesce statements, it would be an absolute
mess to do that.
Whereas you can write this stuff in just a single line of a Cipher.
So, one of the data sets on the sandbox is on the -- it's like -- sorry, my mind has
Basically, like locations.
So, you can say find me the shortest path between -- or how would I get from a coffee
shop to the Statue of Liberty, and you can follow that path through the database to find
And that would be really hard to do in a relational database.
But out of the box --
JASON: Isn't that the traveling salesman problem, the one we decided is interactable?
Is that solved with a graph database, or is it -- I suppose it's not the most mathematically
provable optimal point.
It's just the best point based on the data we have.
But that's still a very hard problem to solve.
ADAM: Yeah, I remember a very cold night where I was on location with a client and speaking
to a couple of people to say how would you actually do this, this traveling salesman
problem in Neo4j.
They were like, why would you bother?
Basically, what you can do is you can -- finding people -- yeah.
JASON: I was curious if we want to play six degrees of Kevin Bacon, we can filter on the
other -- wait, this would be -- yeah, node, person, Keanu Reeves, and we end up with all
And we could probably set -- sorry, I cut you off while you were talking about that
traveling salesman problem.
ADAM: I was going to say, this is where Java comes in.
The J is Java, don't need to use Java.
So, for 99% of use cases, it's good enough to write Cipher.
If it's something too difficult to represent in Cipher or something that's computationally
heavy, then you could write a store procedure in Java to do the traverse.
I spent a lot of time writing those, as well, which is an experience.
So, what if we do want to play six degrees of Kevin Bacon, where what we're trying to
do is determine what is the path between actors acting in movies to get to Kevin Bacon?
So, we want to take a starting actor, and only traverse through movie nodes and actor
nodes to get to Kevin Bacon.
Can I express that in Cipher?
ADAM: Yes, there's a shortest path function in Cipher that you can use for this kind of
You would do P equals shortest path, and in brackets do the pattern that you're looking
JASON: Camel-case, snake-case?
ADAM: Bracket around that.
JASON: Square boy?
JASON: All right.
ADAM: Where you've got star-6, you're saying right now, find me anything through six relationship
What you can do is say colon, and then it would be -- so, acted in would be the relationship
type you're looking at.
Or you could say directed, as well.
So, if you do like a pipe, and then directed.
ADAM: Then if you do star 2.. -- upper limit of 5 or 6, I guess.
JASON: Six degrees of Kevin Bacon.
So, we'll be faithful to the -- and do we need to make this an arrow?
So, you would go outwards from the Kevin Bacon node, into a movie node, but then the relationship
from the other side would be an incoming one.
So, that relationship -- so, sorry, into that node.
So, you would leave off the relationship to that point.
If you wanted to say go down a road in one direction, then you could use that.
Yeah, in this case, we wouldn't.
So, what you're saying is find me the shortest path between a node of a name property of
Kevin Bacon, through acted in or director relationships from two to six degrees, to
another node, where the person name there, and the name Keanu Reeves.
JASON: Oh, does not support minimal length different from 0 or 1.
I screwed something up.
ADAM: So, take off the colon before "directed."
So, it's the same relationship type.
JASON: Oh, I understand.
So, now this should work?
If I cross my fingers.
What have I --
ADAM: Sorry, if you take off the 2, so it's just . .6.
Anything up to six degrees.
JASON: There it is!
ADAM: Tremors with Fred Ward.
JASON: Give us someone else.
Six degrees of Kevin Bacon with Neo4j.
ADAM: From up until like the early 2000s.
(Laughing) I should know, but I don't know what the longest
JASON: Nicolas Cage, The Croods.
Clint Eastwood, here we go, one more time.
They were just in Mystic River together.
I love this.
This is so much fun.
You know, like, these -- so, there's part of this, which is magic is draining out of
the world, because now you don't have to remember things.
You can just Google all of it, and it will be solved instantly.
But, on the other hand, how magical is it that this really challenging thing of, you
know, digging through tons and tons of information, this happened in milliseconds.
And we were able to solve this problem.
That is unbelievable.
So, this is extremely cool.
So, a question here is, can this interface display any graph data from any graph database,
or only data in Neo4j?
ADAM: So, this is just Neo4j, yeah.
And then Jacob is asking, can we filter based on connecting nodes?
Like only sci-fi movies, see how people are connected together?
ADAM: Yeah, so you'd just define, when you write the pattern -- so, we have a simple
pattern there, but define going through to a movie, which then had a property of sci-fi.
JASON: Genre of sci-fi, yeah, okay.
Yeah, that is very, very cool.
This is really, really interesting, because I'm very excited about the possibilities here.
Based on that, how would I get a dataset in here?
We talked a little bit about what if we load in all the "Learn With Jason" episodes.
We've got, I think 270 now, and there's a lot of information in here.
So, how would you pull that in to make it a Neo4j database?
ADAM: So, yeah, that's important.
Your episodes, create a little bit of a graph out of that.
So, I have API episodes here.
And this will get, like, the first 50.
And if we want to get all of them, I think it's page two.
Yeah, so, I've got them paginated, but this will give us at least the first 50.
ADAM: What is the best way for me to send you through something I prepared earlier?
JASON: Through it into probably our Twitter DMs would be the easiest.
I wrote all this, this morning.
The most common way people would import data into Neo4j would be through CSV files, have
them in a certain format, and, yeah, off you go.
So, there's a load CSV command you can do that with.
Because this is JSON format, like I said earlier, if there's things that are hard to express
in Cipher or not possible to do in Cipher, you can write Java to do that.
A set of procedures and functions do a lot of the hard stuff for you.
You can connect directly to a database.
In this example, load in a list of JSON.
So, copy that first line and load it into the sandbox.
JASON: So, I'm going to go up here.
So, what this will do is go away, get the JSON, and then you get basically one row per
item in that JSON array.
So, all of the properties there that we can work with.
So, I was a little bit disappointed the tags were null on everything, because that would
have saved me a job, but I've written the thing to create tags.
JASON: Yeah, dang it.
My older episodes have tags.
Yeah, we fell off on that.
ADAM: Sorry to call you out.
Yeah, so, when you call a procedure, you yield a value.
So, every item in the array of that JSON will be a vary that gets added in.
Then you can use either the merge or create keyword to create data.
So, create will create a node regardless.
What nodes will do is kind of like an upstart.
Look for the data, if that data doesn't exist, it will create it.
What this is saying is create a node with a label of episode with the ID of the underscore
JASON: Sanity, yeah.
So, if that node doesn't exist, then set a node.
So, set a time and values.
So, this on line 11, this is kind of inspired by GraphQL.
Kind of goes both ways.
So, for everything inside value, you can do dot something to pull that out.
Or say, for example, the slug, because it's a nested item.
So, lines 14 to 16 are commented out, because there's always only one host.
Let's not worry about that.
And then inside each of the values, the guest is an array.
So, what this is saying is for each of the values inside that array, create a person
node with the name of the guest.name property.
So, adds that value in.
Submit additional properties, and then merge a relationship between the episode and the
guest to say that the episode has guest.
ADAM: So, if you want to copy and paste all of that in.
JASON: The whole thing here?
ADAM: Yeah, yeah.
I'm going back to here.
ADAM: Cross my fingers it's all okay with the rest of the data there, as well.
ADAM: Should be fine.
JASON: Added 92 labels, created 92 nodes.
ADAM: Cool, if you click on episode.
Yeah, node labels.
Then double click one of those.
So, that is Taylor Barnett serverless something.
Cool, go back to the gist again.
JASON: Back to the gist.
ADAM: Next one -- sorry, the bottom one, tags.Cipher.
This is a rudimental way to create some tags.
Split it by space, so you get every individual word inside there.
Doing a filter to stay, only use the words where -- sorry, when you had with, it was
in lower case.
I thought if we only use the stuff that's an upper case, that might remove stock words.
In theory, you want to remove stuff like "I, am, the," stuff like that.
That's what that does.
There's an apop function that removes everything that isn't alphanumeric and converts to lower
If you spelled Jamstack in two different ways, that represents one label.
Then it creates a tag using that word.
Then creates a relationship between the two.
So, if you copy up until line 20.
You can probably run them both, actually.
JASON: Let's start here, and make sure that it's doing what we expect.
There it goes.
There they are.
So dang cool.
And then down here, we're deleting the noisy ones.
Like I use the word "build" in just about every title, so it's not particularly helpful.
"Your, learn," yeah, those will all be the same.
So, I can take this, and this will let us get rid of some of the messier ones, like
this one here.
So, then I get back here.
And now we have -- well, this is 25 tags, but we have quite a few here.
So, that's limited to the first 25, so no one blows up the database.
Yeah, so, if you double click on one of those, you should see some relationships.
JASON: Let's try one that is going to be functions.
We've got a lot of episodes about functions.
Apparently, two episodes about functions in the last 50.
Yeah, so, the ratio has been credited between those two.
If you head back to the gist again.
There's the second one is basics.
And some codes for exploring.
So, in the first one, like I said, every node is aware of the incoming and outgoing relationships
that are connected.
Also, they keep like a count of these relationship types, as well.
This will show you the most popular tags.
So, based on the size of the -- or the count of the number of has tags relationship going
into that T node, if that makes sense.
JASON: Got ya.
Doesn't seem happy about this.
Wait, let me hover.
What's it say?
This feature is deprecated and will be removed in future versions.
ADAM: Shouldn't be.
Okay, I put something in the show notes, I guess, if and when that gets taken away.
Yes, these are the most popular tags.
So, recently, I guess in the last 50, talk about next.js.
JASON: Jamstack, SQL, serverless, yeah, these all track.
ADAM: We can now sort of explore that from a particular tag, like what episodes are tagged
with a particular tag, or we could see four.
I think the bottom query is the most similar episodes to a particular one.
If we take this one, for example, we could find out based on those tags which would be
the most similar to it.
I guess this is not the best example.
If you run it, you should see some results.
So, before, where you were returning N and M in the queries, you were returning graph
objects, nodal relationships.
Neo4j browser will display those as a graph, or you can switch to table view.
Now, because we're returning only properties and not actual graph things, you get a table
JASON: Got ya.
So, in this particular instance, what we have done is we're saying I want episodes that
have a tag, and then we go the other way.
So, we're going -- both relationships go into the tag.
And then these episodes have two tags in common, and, therefore, would be the most related.
JASON: Okay, this makes me want to load up my -- if I reuse these -- well, I guess we'd
have to do a whole bunch of work to get the tags parsed out in the older stuff.
ADAM: Yeah, there is a quick way to do it.
Unwind statement, which turns a list of things into one per row.
A range of two to 50, load that page, load it in, go from there.
Because these are very small databases, it could cause issues.
All right, I can see how useful this could be, because this, rather than being, say,
show me all the episodes tagged with Jamstack, I'm instead saying show me the episodes that
have the most tags in common with the current episode, and I can kind of filter that.
And then I can prioritize, of course, and say, you know, out of the ones that I get
back, you know, grab the ones that have serverless or whatever first.
But this does a huge amount of filtering, and what would have been manual work for me
to pull all of the tags, do some parsing to figure out which episodes were in both lists,
and then, you know, combining all of that.
The graph just does that for us.
ADAM: Uh-huh, yep.
JASON: And that is really handy.
Like really, really useful.
I'm already -- I've already got it in my head now, how could I use this in a way that would
improve episode recommendation.
Because right now on the website there is no episode recommendation, because I don't
have an easy way to do it.
And this actually kind of solves that problem, if we get back into tagging episodes.
If we get all the episodes tagged, then we have quite a bit of immediate improvement
to the quality of the website, because we can recommend episodes that will kind of lead
somebody through a learning journey, a related learning journey, instead of saying, yeah,
you're here about this episode, and we think you might be into these ones, or me showing
my personal favorites, which, you know, that's what the home page is for, right?
So, if we take it to the next step back, as well, what you could do is create a hierarchy
Like Jamstack, next.js could all be under Java code.
There's a problem with the cold stack problem.
How do you provide recommendations, where no data exists, basically.
JASON: Got ya.
ADAM: So, you can use content-based recommendations.
Then you can use collaborative filtering, which is people have bought this, also bought
That sort of thing.
What you could say, instead of just going to that, the first tag, you could go to the
tag, and then optionally go to the parent, and see anything that's tagged in the parent.
Or things that are tagged with something that belongs to that parent, and traverse through
the hierarchy up and down.
Yeah, and find the data that you're looking for.
JASON: That is, yeah.
And I can see -- one of the challenges that I have run into with data in general is that
I will get too gung ho about trying to categorize, tag, and getting structured with my data,
thinking I'm going to do things like this.
And the level of difficulty to both keep up with it, as we've seen here, I can't even
be bothered to do straight tagging, let alone going in and doing really hierarchical stuff.
But when it's easy to use the results of that effort, the incentives change a little bit.
Right now, when I tag, in the future some day I'll use this, therefore, it falls off
the priority list, because I'm not using it right now.
If I have a way to display recommendations based off of tagging, it makes the content
more useful, that changes the priority list a little bit.
Now I have a reason to go and do this.
That also is, you know, it's a good, I think, example of the business value of looking at
the right technology for the job.
If I have a graph database, suddenly certain things that are extremely valuable, like recommendation
engines, aren't quite the technical hurdle that they would have been -- you know, right
now I'm using a fairly relation database, and it's good.
There's nothing wrong with the database that I'm using, but it doesn't have -- it's not
It's not immediately showing me, yeah, these are episodes most similar based on tags.
That's the sort of thing that I think is, you know, pretty dope as a user of a technology
whatever coding language of pulling data and getting it combined, doing sorting, testing,
and making sure I didn't accidentally create a bunch of crap because I over-queried.
All these questions that I have sort of avoided with these four lines of Cypher code.
ADAM: Yeah, definitely.
This is sort of scratching the surface.
Cypher is like a procedural language, as well.
You can do lots of things with it.
You could do reads and writes inside the same query.
You could use the width clause to do sort of pre-processing.
What you could do, instead of return the value, you could say with E1, E2, and the collection
of them, and create a direct relation between them, and do that in one query.
You could do a lot inside one query that you maybe wouldn't do -- it would take you three
Yeah, just getting your head around what the possibilities are, and not being too sort
of styled and shocked by them to actually do them.
Yeah, this is -- a lot of possibilities here.
I feel like, chat, how excited are you to dig into graph databases right now?
Like what ideas are you having looking at this that you want to go dig into now that
you've kind of seen what is possible here?
As an example, something that I'm thinking about right now, is there a way that I could
do a round of tagging, but then also allow people to add their own tags to episodes,
which would then let people kind of improve the recommendation engine by tagging episodes?
We'd probably have to come up with a way to show what's been tagged so you don't get duplicates
and things like that, but it could be an interesting way to improve the quality of the show.
Someone saying autonomous vehicle path planning.
That is, yeah, a great use of that kind of graph database thing.
ADAM: May already be being done.
I cannot confirm or deny.
JASON: Decentralized real-time apps and chats.
Yeah, I can see that being a thing.
Is there a lot of real-time support here?
What's that look like?
Can you do subscriptions or Web Socket or anything like that?
ADAM: Not at the moment.
A couple of years ago I wrote a blog post on how to do it, because I wanted to do it
on my own websites.
So, basically, there's a connector that you can plug in.
Basically, like a few lines of config in the new file, you can set up like a publish sort
of loop to publish to Kafka.
What I did was consume that in a node.js application and put web sockets in the front end.
That's the way to do it at the moment.
Neo4j library doesn't support them at the moment, but I'm told it's on the road map,
but I don't know where on the road map that would be.
Yeah, I guess Kafka, something like that, would be the best option.
Or I guess anything like that, that supports Java, you can write Java extension that pings
out a message when something happens.
JASON: Uh-huh, yeah.
So, maybe a question to ask here, as we're coming to the end and we're really hyped on
this, what are the situations where you wouldn't reach for a graph database?
Where do you see the limitations or the tradeoffs?
ADAM: So, the one criticism that I probably shouldn't admit this, but one of the criticisms
of Neo4j is kind of the write performance.
So, if you want something -- I'm talking like real sort of high end, if you want real high
throughput, and you want to add billions of records per second into a database, then Neo4j
isn't necessarily the thing for you.
But equally what you could do is take an aggregate view of that, put that into Neo4j, and use
that for the graph-y problems.
Yeah, you could have -- maybe like a social network where your data was stored in a -- your
favorite document store.
And then you take the aggregation to one side, or you take the friends and followers type
things to one side.
And that would live in the graph database.
Yeah, you could quite easily build a connector that ports in data.
Netlify, right, just run one of those to take an aggregate view of the data for the last
ten minutes, put it in a database, and go from there.
Yeah, the right throughput is probably if you want something huge, then that's probably
not for you.
But Neo4j can be used as a general database.
Like it's not -- I guess the myth is, it's a niche thing, but you can use it today on
your next project.
So, that's -- maybe the other question here would be we looked into how to get data in
And we looked into kind of how to query that data.
When I want to get data out of Neo4j, how does one do that?
And is it the sort of thing where we can build a really rough proof of concept in ten minutes,
or should we share resources instead?
ADAM: I'm up for the challenge in doing it in ten minutes.
JASON: I'm so ready, let's do it.
I'm going to make a new directory called Neo4j -- I'm going to -- there.
What are we doing?
There, all right.
Let me get in it.
So, we have an empty folder.
What should I do?
Is there a certain starter I should use, should we query direct?
What do you prefer?
ADAM: Let's go direct.
And there's community drivers, as well.
So, if you create a new index.js or main.js or something.
JASON: Are we running this as node?
JASON: So I'm going to build this as a Netlify function.
And then we're going to touch Netlify functions, and we'll call this data there, and I'm going
to open this up, so we can code in there.
So, I have data.ts, and we have the Neo4j driver available.
JASON: I'm just going to set up the base here.
So, we're going to return a status code of 200, and we're going to return body for now
of just okay.
And now we're ready to pull in the Neo4j driver.
ADAM: So, if you import Neo4j from Neo4j driver.
That gives you a function called driver that allows you to create new instances for the
Const driver -- not new, just Neo4j.driver.
So, this takes two arguments.
The first one is the uri of the instance, second is a token.
If you go into your sandbox, I think it's -- sandbox.Neo4j.com.
Go into connection details.
Copy that bolt URL, that's your first argument.
Then you need an auth token.
And then the user name is going to be Neo4j for this instance, and the password you should
be able to copy from there, from the UI.
ADAM: Cool, perfect.
That's the instance of the driver.
Through the driver, create a session.
And then the session basically manages what the connection to the database.
So, I guess inside the handler, you would do that.
Sessions are like lightweight things, you can pull them up and tear them down as you
JASON: Like that?
With brackets, as well.
JASON: All right.
So, then I'm going to be able to do stuff.
And I want to begin a transaction.
ADAM: So, there are four ways of doing this.
The quickest way would be to do session.run.
Let's go with that for now.
In production you wouldn't do this, but because we've only got four minutes.
JASON: Does it return a promise, do we need to await it?
ADAM: Yeah, yeah.
ADAM: Function, so the first is the Cypher query.
If you do match and return, something like that.
And in brackets, return, count, n.
JASON: Like that?
ADAM: Yeah, and do as count.
So, the second argument, you can add parameters into there, as well.
There's a map.
You don't need to worry too much about that.
So, that response gives us some information, but the main thing on there is a records array.
ADAM: I guess this is only one.
So, if you do return labels bracket -- sorry, comma.
Yeah, so, labels.
Like a labels.
Then open bracket.
"N." Then closed bracket.
Then a comma.
So, what --
JASON: Like this?
So, for each one of the labels, give me a count.
Each combination of labels.
JASON: Got ya.
ADAM: So, records gives you -- records is an array.
You can call map on that.
Do I want to do that, or can we just dump the data and see?
ADAM: Yeah, yeah, you can do it, yeah.
JASON: All right.
Let's just start by running this.
I'm going to run Netlify dev to get that function running.
Then I'm going to go out here and do Netlify functions.
What did we call this?
We called it data.
And we get back data.
So this is like the rule record.
If you do .map, that gives you an individual record.
With that, you can call .get to get the individual item.
So, we're going to do response.records.map.
And then that will give us a record.
And we wanted to return what now?
ADAM: So, if you say -- if you return a new object.
Sorry, what you could do is do record.two objects.
And that will give you the object.
JASON: Like that?
JASON: Okay, return records.
And we can come back out here and test it.
ADAM: Labels and the count.
I love this.
ADAM: There's one got you in there.
With the count, see there's a high and a low on there?
Again, Neo4j is written in Java.
So, for each integer, you have to call two number on it in order to convert it back into
Otherwise, it kind of lost it.
I came up with this number.max, underscore something limit.
If it goes above that, convert it to a strong, which means you don't lose it.
JASON: Got it.
So, if I do like -- record object equals, and then I can return instead labels would
be record, object --
ADAM: You could do record.get, rather than create the record object.
JASON: Oh, oh, oh.
So, I could do record.get.
And I'm making that inference off of this, right?
ADAM: Uh-huh, yep, yeah.
JASON: And then here I can get the count.
And that's going to be record.get.count.
And then you said to number.
Look at it go.
So, I mean, this is perfect.
This is exactly what we were after.
And we didn't have to write a whole lot of code.
And at this point, you know, we would do most of the work in Cypher, and then we'd just
pull out the pieces that we're trying to get, do a tiny bit of massaging to get Java and
If we wanted this to improve, I could just change this to be as labels, right, and then
I can change this to labels.
And out here.
Nothing changes visually, but our code looks a little bit less magical, right, we've set
the names of things.
So, they work the way we expect.
JASON: Chat, is this dope, or is this dope?
Can I get a "W" in the chat?
Yeah, so, okay.
This is very cool.
I don't think we're going to have time to dig too much deeper than what we've done now.
I will publish this example.
Is this going to self-destruct?
ADAM: So, that will disappear at some point, if you don't -- it will terminate.
If you convert those to environment variables, then that should be good enough, and they
set their own environment variables and go from there.
JASON: What I'm going to do, I'm not going to publish this as a running site, but what
I'll do is call this Neo4j bolt URL.
And then we'll also get -- bolt password.
I guess this would be Neo4j --
ADAM: So, Neo4j.auth.basic, then user name and password.
JASON: User name doesn't change.
ADAM: Sorry, looking at the wrong line.
So, this basic setup here.
Do I need to install node definitions?
But I'll put this up as a code sample for anybody that wants to see how to pull Neo4j
In this particular instance, we're doing it via serverless functions on Netlify.
And this requires a node environment, I'm assuming.
I wouldn't run this client-side, because there's passwords.
So, you can, but it's probably recommended not to.
You can build things called graph apps for Neo4j desktop.
Use the driver to connect over the browser.
So, Neo4j browser is a React application that uses the driver, but you have to add in your
own credentials there.
So, yeah, storing those credentials probably isn't the best idea.
Have I seen people do it?
Yeah, of course.
JASON: Honestly, if you want to use it on the client side, throw it in a serverless
function like we did.
This keeps credentials secure, and we get this data.
We can call this from our client-side code and no one can get at the user name or password,
only what we query.
As far as we know, roughly equivalent.
Write the code we want, call this data function, instead of calling this Neo4j directly from
the client code.
We get the convenience, as well as not standing up a node server to run it.
With that, I think this is probably as good of a time as any to start asking you, what
are some good resources for somebody who is looking to take this further?
Where should you go next if you're excited about Neo4j and want to learn more?
ADAM: If you want to have a play around, I would go to Neo4j Sandbox.
If you seen what you like but want to import data in, Aura, set up an account, create a
free instance, and start to play from there.
If you want to learn more, there's the developer pages at Neo4j.com/developer, which gives
you developer guides on how to get started.
But what I would recommend is a course I've just written for app development with Node.js
is on Graph Academy.Neo4j.com.
My day job is Graph Academy.
There's a course for Python, if you're not a big fan of Node.js.
Yeah, if you scroll down a little bit, and then go to -- curated learning paths.
So, those are the two.
So, the Node.js course is a good one to start.
Basically, what you do, I've prebuilt a repository with hard code varies in there for a fictional
client, and you go through and learn.
If you click on table of contents, you learn, it will create a Neo4j Sandbox for you and
challenges you on data that's held in Sandbox.
Teaches you about the driver, how sessions work, why you shouldn't use session.run, you
should use read and write transactions, type systems, and the differences there, as well.
And, yeah, at the end of it, you get a nice badge that goes on your public profile that
you can share with your friends, colleagues, potential employers, me, share it on Twitter.
Yeah, do what you need to.
JASON: All right.
So, everybody, you got your homework.
You're going to go follow Adam for all the Twitter goodness, learning more about Neo4j
in not just Java.
Python, Node, Java.
Did I see .net in there?
ADAM: Coming soon.
We're a small team on Graph Academy.
JASON: Sure, sure, but lots of potential, lots of cool things to do.
I'm really excited about the, you know, just what's possible with graph databases.
Again, just going back and looking at this, what we were able to accomplish in very little
We got, you know, data loaded in, we were able to play seven degrees of Kevin Bacon,
which is really a fun game to play.
Just lots of cool things happening here.
With that, let's go and give another shout-out to our live captioner.
We've had Ashly here today from White Coat Captioning.
Thank you so much, Ashly.
For being here and taking all these notes for us.
And that's made possible through the support of our sponsors, Netlify, Nx, and Backlight,
are all kicking in to keep the lights on the show.
They cover the cost of live captioning, also covered by your subscriptions.
I saw a few of you subscribe today, thanks a lot, means a lot.
Please, boop the heck out of us to celebrate your subscription.
While checking out the home page, head over and check out the schedule.
We've got so much good stuff coming up.
We are going to be -- I'm out next week, actually.
I'm going to be taking some much-needed time off.
If you haven't booked your PTO yet, book some PTO.
Take care of yourselves, let's try not to burn out.
When we come back, product announcement, and Sean Grove, lead engineer at Netlify is going
to show us how it all works.
We're going to get into Eleventy Serverless, David is coming back, B. Dougy, one of my
favorite people, and much, much more.
So, please, get out there, check that schedule.
Add us on Google Calendar.
With that, Adam, any parting words for the chat?
ADAM: Thanks for, yeah, thanks for following along and sticking along to the end, as well.
One thing I should shout-out is Neo4j have their own Twitch
channel, as well.
Some of my colleagues in the dev rel team run weekly sessions.
So, Alex, who's been answering some of
the questions in the chat that I've seen, hosts that with Michael.
Yeah, all sorts of different topics and things.
If anyone wants to see anything else, feel free to
get in touch.
We can see what we can put together.
All right, with that, we're going to call this episode a soaring success.
Thank you all for hanging out with us today, thank you, Adam, teaching us about Neo4j.
We're going to raid Alex trough's, so, everybody, stay tuned and join along in the raid.
Adam, thank you for hanging out
see you all
Closed captioning and more are made possible by our sponsors: