Twoja pierwsza próba jest prawidłowa, ale musisz użyć (częściowych) indeksów btree i skanowania indeksów bitmap, aby na nich polegać:
create index on product(((ext->'size')::int)) where ((ext->'size') is not null);
To samo dla masy, a jeśli planista nie dostanie tego na miejscu, dodaj dwie klauzule where, tj. where ext->'size' is not null
i to samo dla masy.
Jeśli istnieje jakiś wzór (co jest prawdopodobne, ponieważ większość produktów o rozmiarze ma również masę), potencjalnie utwórz indeks wielokolumnowy łączący dwa - jeden worek, drugi opis.
Indeks gin tak, jak go napisałeś, wraz z towarzyszącym mu zapytaniem (z błędem składni) zasadniczo zrobi to samo, ale nieuporządkowany; będzie wolniej.