Я пытаюсь использовать оператор существующего jsonb '?' в конструкторе запросов Laravel, и он использует индекс, но я столкнулся с некоторыми проблемами.
Пример запроса
DB::table('table_name')->whereRaw("jsonb_column ? 'key'")->get();
Пример индекса
CREATE INDEX ON table_name USING GIN(jsonb_column jsonb_ops)
Основная проблема заключается в том, что '?' зарезервирован для замены параметров, поэтому этот запрос возвращает синтаксическую ошибку. Я нашел несколько способов обойти это, но каждый из них является неполным решением.
используйте '??' (способ избежать?) ->whereRaw("jsonb_column ?? 'key'")
- не работает с построителем запросов. возвращает
SQLSTATE[42883]: Undefined function: 7 ERROR: operator does not exist: jsonb ?? unknown
- работает с необработанными запросами, например,
DB::select("SELECT * FROM table_name WHERE jsonb_column ?? 'key'")
, но мне нужно, чтобы он работал с построителем запросов.
use именованная функция / создать псевдоним для оператора
- '?' переводит в функцию - jsonb_exists (jsonb, текст)
->whereRaw("jsonb_exists(jsonb_column, 'key')")
CREATE OPERATOR @-> ( PROCEDURE = jsonb_exists, LEFTARG = jsonb, RIGHTARG = text );
->whereRaw("jsonb_column @-> 'key'")
- оба решения "работают" ... но они не используют индексы
Сейчас я исследую CREATE OPERATOR CLASS
, как способ чтобы мой пользовательский оператор использовал индексирование джина, но это немного над моей головой. Если кто-нибудь может дать мне несколько советов о том, как выполнить sh это или, что еще лучше, какое-нибудь более простое решение, это будет огромной помощью.
edit