sql >> Databasteknik >  >> RDS >> PostgreSQL

Hur man undkommer frågetecken (?) med Spring JpaRepository

Om du undkommer ? är inte möjligt, du kan skapa dubblettoperatör med annat namn.

Ny operatör

Syntax för att skapa operatorer i Postgres:

CREATE OPERATOR name (
    PROCEDURE = function_name
    [, LEFTARG = left_type ] [, RIGHTARG = right_type ]
    [, COMMUTATOR = com_op ] [, NEGATOR = neg_op ]
    [, RESTRICT = res_proc ] [, JOIN = join_proc ]
    [, HASHES ] [, MERGES ]
)

I fallet med ?| används i jsonb det blir:

CREATE OPERATOR ^|(
  PROCEDURE = jsonb_exists_any,
  LEFTARG = jsonb,
  RIGHTARG = _text,
  RESTRICT = contsel,
  JOIN = contjoinsel);

Jag har använt ^| som ett exempel, alternativt namn. Det kan vara vilken sekvens som helst från denna lista:+ - * / < > = ~ ! @ # % ^ & | ?`.

Du kan hitta aktuell definition för operatorn du är intresserad av genom att fråga pg_catalog.pg_operator table.

SELECT oid, *
  FROM pg_catalog.pg_operator
 WHERE oprname = '?|'
   AND oprleft = (SELECT oid FROM pg_type WHERE typname = 'jsonb');

Du kan också använda GUI-verktyg som pgAdmin och bläddra i pg_catalog för att få SQL-definitionen redo för återanvändning.

Aktivera index

Om du vill använda index för denna "nya" operatör måste du skapa en ny operatörsklass och eventuellt familj. I vårt fall behöver vi båda, eftersom vi inte kan lägga till det i befintlig familj, eftersom standardoperatören redan tar strategiplats.

Precis som med operatorer, rekommenderas det att använda GUI-verktyg som pgAdmin för att bläddra i operatorklasser och bara kopiera och klistra in det.

Först tar vi OID för operatören vi gjorde duplikat av:

SELECT oid, *
  FROM pg_catalog.pg_operator
 WHERE oprname = '?|'
   AND oprleft = (SELECT oid FROM pg_type WHERE typname = 'jsonb');

Samma sak för operatörsfamiljen (vi kommer att få det från operatörsklasstabellen istället), vi letar efter ginklass eftersom det här är den som stöder ?| . opcdefault används, eftersom det finns valfri klass jsonb_path_ops som inte stöder denna operatör:

SELECT opcfamily
  FROM pg_opclass
 WHERE opcintype = (SELECT oid FROM pg_type WHERE typname = 'jsonb')
   AND opcmethod = (SELECT oid FROM pg_am WHERE amname = 'gin')
   AND opcdefault

Sedan får vi strategi som används av operatören vi duplicerade:

SELECT amopstrategy,
       (SELECT typname FROM pg_type WHERE oid = amoplefttype) AS left_t, 
       (SELECT typname FROM pg_type WHERE oid = amoprighttype) AS right_t,*
FROM pg_amop
WHERE amopfamily = 4036 --family oid
  AND amopopr = 3248 --operator oid

Sedan funktioner som används av klass:

SELECT amprocnum, amproc::text, pg_get_function_identity_arguments(amproc::oid) AS args,
      (SELECT typname FROM pg_type WHERE oid = amproclefttype) AS left_t,
      (SELECT typname FROM pg_type WHERE oid = amprocrighttype) AS right_t,*
FROM pg_amproc
WHERE amprocfamily = 4036 --op family

Detta för oss till denna operatörsklass. Den kommer att skapa operatörsfamilj om den inte redan finns.

CREATE OPERATOR CLASS jsonb_ops_custom
   FOR TYPE jsonb USING gin AS
   OPERATOR 10  ^|(jsonb, _text),
   FUNCTION 1  gin_compare_jsonb(text, text),
   FUNCTION 2  gin_extract_jsonb(jsonb, internal, internal),
   FUNCTION 3  gin_extract_jsonb_query(jsonb, internal, smallint, internal, internal, internal, internal),
   FUNCTION 4  gin_consistent_jsonb(internal, smallint, jsonb, integer, internal, internal, internal, internal),
   FUNCTION 6  gin_triconsistent_jsonb(internal, smallint, jsonb, integer, internal, internal, internal);

Nu behöver du bara skapa index med operatörsnamnet som skapades, något i stil med:

CREATE INDEX ON jsonb_table USING gin(jsonb_column jsonb_ops_custom)

Och du bör kunna använda index:

SET enable_seqscan = off;
EXPLAIN ANALYZE
SELECT * FROM jsonb_table WHERE jsonb_column ^| array['b', 'c'];


  1. Hur man ställer in MySQL-replikering i RHEL, Rocky och AlmaLinux

  2. PostgreSQL returnerar en funktion med en anpassad datatyp

  3. Bästa praxis för flerspråkig databasdesign

  4. Hur man behåller data i en dockeriserad postgres-databas med hjälp av volymer