How to use Postgres jsonb '?' operator in Laravel with index support?

早过忘川 提交于 2020-06-17 09:17:04

问题


I'm trying to use the jsonb exists operator '?' in Laravel's query builder, and have it use an index, but I've run into some issues.

Sample query

DB::table('table_name')->whereRaw("jsonb_column ? 'key'")->get();

Sample Index

CREATE INDEX ON table_name USING GIN(jsonb_column jsonb_ops)

The main issue seems to be that '?' is reserved for parameter replacement, so this query returns a syntax error. I've found a couple ways around this, but each are incomplete solutions.

  1. use '??' (a way to escape the ?) ->whereRaw("jsonb_column ?? 'key'")

    • doesn't work with querybuilder. returns SQLSTATE[42883]: Undefined function: 7 ERROR: operator does not exist: jsonb ?? unknown
    • works with raw queries, e.g. DB::select("SELECT * FROM table_name WHERE jsonb_column ?? 'key'"), but I need it to work with the query builder.
  2. use a named function / create an alias for the operator

    • '?' translates to the function - jsonb_exists(jsonb, text)
      • ->whereRaw("jsonb_exists(jsonb_column, 'key')")
    • CREATE OPERATOR @-> ( PROCEDURE = jsonb_exists, LEFTARG = jsonb, RIGHTARG = text );
      • ->whereRaw("jsonb_column @-> 'key'")
    • these solutions both "work"... but they don't use indexes

Right now I'm researching CREATE OPERATOR CLASS, as a way to get my custom operator to use gin indexing, but it's a bit over my head. If anybody can give me some tips on how to accomplish this or, even better, some simpler solution, it'd be a huge help.

edit

  • using php 7.3

回答1:


PHP 7.4 allows you to escape the placeholder with ??: https://wiki.php.net/rfc/pdo_escape_placeholders

DB::table('table_name')->whereRaw('jsonb_column ?? ?', ['key'])->get();


来源:https://stackoverflow.com/questions/60310077/how-to-use-postgres-jsonb-operator-in-laravel-with-index-support

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!