Mastering Postgres
Introduction
Introduction to the course
Overview of course structure
Postgres vs. everyone
The psql CLI
Data Types
Introduction to schema
Integers
Numeric
Floating point
Storing money
NaNs and infinity
Casting types
Characters types
Check constraints
Domain types
Charsets and collations
Binary data
UUIDs
Boolean
Enums
Timestamps
Timezones
Dates and times
Advanced Data Types
Intervals
Serial type
Sequences
Identity
Network and mac addresses
JSON
Arrays
Generated columns
Text search types
Bit string
Ranges
Composite types
Nulls
Unique constraints
Exclusion constraints
Foreign key constraints
Indexing
Introduction to indexes
Heaps and CTIDs
B-Tree overview
Primary keys vs. secondary indexes
Primary key types
Where to add indexes
Index selectivity
Composite indexes
Composite range
Combining multiple indexes
Covering indexes
Partial indexes
Index ordering
Ordering nulls in indexes
Advanced Indexing
Functional indexes
Duplicate indexes
Hash indexes
Naming indexes
Understanding Query Plans
Introduction to explain
Explain structure
Scan nodes
Costs and rows
Explain analyze
Generating Results
Introduction to queries
Cross joins
Inner joins
Outer joins
Subqueries
Lateral joins
ROWS FROM
Filling gaps in sequences
Subquery elimination
Combining queries
Set generating functions
Indexing joins
Advanced SQL
Introduction to advanced SQL
Grouping
Grouping sets, rollups, cubes
Window functions
CTEs
CTEs with window functions
Recursive CTE
Hierarchical recursive CTE
Handling nulls
Row value syntax
Views
Materialized views
Removing duplicate rows
Upsert
Returning keyword
COALESCE + generated column
Full Text Search
Introduction to full text search
Searching with LIKE
Vectors, queries, and ranks
Websearch
Ranking
Indexing full text search
Highlighting
Advanced JSON
Intro to JSON
JSON vs JSONB
Validating JSON
Creating JSON objects + arrays
JSON extraction
JSON containment
JSON existence
JSON recordset
Updating JSON
Indexing JSON parts
GIN index
Vectors (pgvector)
Intro to pgvector
Vector embedding columns
Find related articles
Upsert vector embedding
Semantic search
Other operators
Vector indexes
Outro
Thank you
Bonus interviews
Heroku's glory days & Postgres vs the world (with Craig Kerstiens)
Creating a Postgres platform with Monica & Tudor from Xata.io
Bootstrapping an email service provider (with Jesse Hanley)
Locked video

Please purchase the course to watch this video.

Video thumbnail
Vectors (pgvector)
Upsert vector embedding

Full Course

$
349
$399
USD, one-time fee
The course broke down complex subjects into easy-to-understand videos that I've referred back to multiple times since completing it. It strengthened my knowledge by filling gaps and expanding into new areas I hadn't known about—absolutely worth doing!
Lawrence
Lawrence

PostgreSQL database platform

Shorten dev cycles with branching and zero-downtime schema migrations.

Test Data

I've made my test data available for you to use and follow along.

Download
or
Use on Xata

Summary

Learn how to enhance the related products or articles feature by using an upsert to update vector embeddings when product details or articles change. By using unique slugs, you can efficiently manage updates in the database, ensuring the embeddings stay current. This process runs in the background, automatically updating embeddings whenever content changes, keeping your recommendations accurate and up-to-date.

Video Transcript

In the last video, I was terribly excited, right? We created a related products or related articles feature in I think it was under maybe seven or eight minutes. Kind of wild. We're going to make it a little bit more robust here, a little bit more production ready by using an upsert. Because imagine your articles change or your product descriptions change, or your product photos are updated. You need to update the embeddings. We've already learned how we can do upcerts.

We're going to combine that knowledge to up cert our vector embeddings. We're just running this as a single command. You have to imagine this is being run as a background job or some sort of listener or some sort of evented hook, something like that. Whatever your framework or language provides. The situation would be, what if we update an article? If we update an article, we update a product description, we change an image, we need to cue some sort of background job to go get new embeddings and then update the database. We can use the fact that Slug is unique. We can use that to accomplish an upsert.

Let's hop down here and make some space. We'll make some space here. This is our initial statement. These question marks are for bind parameters. We're not just injecting strings in here, which can lead to SQL injection. We're going to say on conflict. Then you pass through the column name. When there is a conflict on the column slug, which is unique, we're going to do update set embedding equal to excluded, which is that keyword that says, hey, you were trying to insert this, but we disallowed it because there was a conflict. Here it is if you want to access it. Excluded.embedding. That should accomplish our upsert. If we hop back over here, we can't just null it out. What I'm going to do is I'm going to say, let's go, let's put the first three values as zero. We'll say 000. Save that, save that.

If we refresh, so you'll see the first three values are zero. I've mucked up the vector embeddings, and now we want to run our worker again and we'll say, AR embed and reputation is portable. That's the very first one. Reputation is portable right here. If we run that again, we see, boom, the upsert worked. So in the real world, you would run this, in the real world, you would run this as the result of saving the model probably, you would save the model. You would check to see, are the contents dirty? Did I change the contents of my blog post or my product description or my image? If so, let's fire off a job to go out, get some new embeddings and then insert it, so you can use those upserts that we learned a long time ago, we can use that to keep those embeddings fresh.