Je eerste poging is correct, maar je moet (gedeeltelijke) btree-indexen en bitmap-indexscans gebruiken om erop te vertrouwen:
create index on product(((ext->'size')::int)) where ((ext->'size') is not null);
Hetzelfde voor massa, en als de planner het niet ter plekke krijgt, voeg dan twee waar-clausules toe, dwz where ext->'size' is not null
en hetzelfde voor massa.
Als er een bepaald patroon is (wat waarschijnlijk is, aangezien de meeste producten met een maat ook een massa hebben), maak dan mogelijk een index met meerdere kolommen door de twee te combineren - de ene zak, de andere beschrijving.
De gin-index zoals je die hebt geschreven, samen met de bijbehorende query (met een syntaxisfout) zal in principe hetzelfde doen, maar ongeordend; het zal langzamer zijn.