GIN — Generalised Inverted iNdex
B-tree indexes one value per row. GIN indexes many values per row — the words inside a text field, the keys inside a JSONB document, the elements inside an array. The 'inverted' part means: for each value, GIN stores the list of rows that contain it (just like a book index).
JSONB containment
The killer GIN use case for JSONB is the containment operator @>: "rows whose JSONB contains this sub-document." Without a GIN index, every row is parsed and checked. With one, it's a direct lookup.
Full-text search
GIN on a tsvector column lets PostgreSQL answer "rows whose document contains these words" in milliseconds across millions of articles — no Elasticsearch needed.