Първоначалният ви опит е правилен, но трябва да използвате (частични) btree индекси и сканиране на растерни индекси, за да разчитате на него:
create index on product(((ext->'size')::int)) where ((ext->'size') is not null);
Същото за масата и ако планиращият не го получи на място, добавете две клаузи where, т.е. where ext->'size' is not null
и същото за масата.
Ако има някакъв модел (което е вероятно, тъй като повечето продукти с размер също имат маса), потенциално създайте многоколонен индекс, комбиниращ двете - една торбичка, другата desc.
Индексът на gin, както го написахте, заедно със съпътстващата заявка (със синтактична грешка) основно ще направи същото, но неподредено; ще бъде по-бавно.