sql >> Database >  >> RDS >> PostgreSQL

Hoe te ontsnappen aan het vraagteken (?) -teken met Spring JpaRepository

In het geval dat u ontsnapt aan ? is niet mogelijk, u kunt een dubbele operator maken met een andere naam.

Nieuwe operator

Syntaxis voor het maken van operators in 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 ]
)

In het geval van ?| gebruikt in jsonb het zal zijn:

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

Ik heb ^| . gebruikt bijvoorbeeld alternatieve naam. Het kan elke reeks uit deze lijst zijn:+ - * / < > = ~ ! @ # % ^ & | ?`.

U kunt de huidige definitie van de operator waarin u geïnteresseerd bent vinden door de tabel pg_catalog.pg_operator te doorzoeken.

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

U kunt ook de GUI-tool zoals pgAdmin gebruiken en door pg_catalog bladeren om de SQL-definitie klaar te maken voor hergebruik.

Index inschakelen

Als u index wilt gebruiken voor deze "nieuwe" operator, moet u een nieuwe operatorklasse en optioneel een familie maken. In ons geval hebben we beide nodig, omdat we het niet aan de bestaande familie kunnen toevoegen, omdat de standaardoperator al een strategieslot neemt.

Net als bij operators, wordt het aanbevolen om de GUI-tool zoals pgAdmin te gebruiken om door operatorklassen te bladeren en deze gewoon te kopiëren en plakken.

Eerst nemen we de OID van de operator waarvan we een duplicaat hebben gemaakt:

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

Hetzelfde geldt voor de operatorfamilie (we halen het in plaats daarvan uit de operatorklassetabel), we zijn op zoek naar de gin-klasse omdat dit de klasse is die ?| ondersteunt . opcdefault wordt gebruikt, omdat er een optionele klasse jsonb_path_ops . is die deze operator niet ondersteunt:

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

Vervolgens krijgen we de strategie die wordt gebruikt door de operator die we hebben gedupliceerd:

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

Dan functies die door de klas worden gebruikt:

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

Dit brengt ons bij deze operatorklasse. Het zal een operatorfamilie maken als deze nog niet bestaat.

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 hoeft u alleen maar een index te maken met de operatornaam die is gemaakt, zoiets als:

CREATE INDEX ON jsonb_table USING gin(jsonb_column jsonb_ops_custom)

En je zou index moeten kunnen gebruiken:

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


  1. Hoe TO_SECONDS() werkt in MariaDB

  2. MariaDB introduceert TO_CHAR()

  3. Top Facebook-groepen voor Analytics, Big Data, Data Mining, Hadoop, NoSQL, Data Science

  4. Hoe MariaDB op CentOS 7 te installeren en te beveiligen