26.6 Modifying JSONB: jsonb_set() and the Concatenation Operator ||

Right, so you’ve got your JSONB document. It’s a beautiful, nested snowflake, perfect and pristine. And now you need to change it. Of course you do. Data isn’t a museum exhibit; it’s a living, breathing, frequently-misconfigured mess that needs constant tweaking. Let’s talk about how to perform surgery on these JSONB structures without leaving a bloody mess everywhere. The workhorse here is jsonb_set(). Don’t let the simple name fool you; it’s deceptively powerful and, like most powerful things, easy to misuse. Its job is to replace or set the value at a specified path.

26.5 jsonb_agg() and jsonb_build_object(): Building JSON in SQL

Right, so you’ve got all this lovely JSONB data sitting in your columns, and you’re probably thinking, “Great, I can query it. But how do I make it?” Because sometimes you need to assemble your own JSON structures on the fly, either to return from an API, feed into another system, or just to show off. That’s where jsonb_agg() and jsonb_build_object() come in. They’re your power tools for constructing JSON directly within a SQL statement, saving you from the nightmare of string concatenation (a path that leads only to madness and escaping errors).

26.4 JSON Path Queries with jsonpath (PostgreSQL 12+)

Alright, let’s talk about jsonpath. You’ve probably been using the -> and ->> operators to navigate your JSONB data, and they’re great for simple, straightforward paths. But what happens when your data structure gets more complex, or you need to do something more powerful, like filtering for elements within an array based on a condition? You start writing these monstrous, nested SQL expressions that are a pain to write and a nightmare to read.

26.3 GIN Indexes on JSONB: jsonb_ops vs jsonb_path_ops

Right, let’s talk about making your JSONB queries not just work, but scream. You’ve loaded up a table with a mountain of JSON documents, and you’re running WHERE data @> '{"status": "published"}'. It’s fast at first, but as your data grows, it starts to feel like wading through molasses. You’ve heard about GIN indexes, the workhorse for JSONB, but then you’re hit with a choice: jsonb_ops or jsonb_path_ops? It’s not just academic; picking the wrong one is like showing up to a Formula 1 race with a go-kart engine.

26.2 JSONB Operators: ->, ->>, #>, @>, ?, ?|, ?&

Right, let’s talk about JSONB operators. This is where you stop just storing JSON and start actually using it. Forget the clunky, string-based horror of json_extract_path_text or whatever your previous database tried to sell you. PostgreSQL gives you a proper set of tools that feel, well, like they belong in a database. They’re the difference between poking your data with a stick and wielding a lightsaber. We’ll break them down into two camps: the path navigators (who get you the data) and the existence checkers (who tell you if something’s there).

26.1 json vs jsonb: Storage and Operator Differences

Right, let’s settle this. You’ve probably already been told that jsonb is the one you should use 99.9% of the time. You nod, you move on. But I know you. You’re the kind of person who needs to know why. Because if you don’t, that 0.1% case will sneak up and bite you in production at 3 AM on a Sunday. So let’s get our hands dirty. The core difference isn’t about what they store—they both store perfectly valid JSON. It’s about how they store it. The json type stores an exact, whitespace-and-all copy of the text you put in. It’s a glorified text field with syntax validation. Need to preserve the exact textual representation for legal reasons or because some external system is ridiculously fussy? Fine, use json. For everyone else, read on.

— joke —

...