これはPGroonga 2.X用のドキュメントです。古いPGroongaを使っているならPGroonga 1.xのドキュメントを見てください。

jsonb型用の@>演算子

概要

PGroongaは@>演算子の検索をインデックスを使って高速に実現できます。

@>演算子はPostgreSQL組み込みの演算子です。@>演算子は右辺のjsonb型の値が左辺のjsonb型の値のサブセットなら真を返します。

構文

この演算子の構文は次の通りです。

column @> query

columnは検索対象のカラムです。型はjsonb型です。

queryはクエリーに使うjsonb型の値です。

この演算子はquerycolumnの値のサブセットならtrueを返し、それ以外の時はfalseを返します。

演算子クラス

この演算子を使うには次のどれかの演算子クラスを指定する必要があります。

使い方

例に使うサンプルスキーマとデータは次の通りです。

CREATE TABLE logs (
  record jsonb
);

CREATE INDEX pgroonga_logs_index ON logs USING pgroonga (record);

INSERT INTO logs
     VALUES ('{
                "message": "Server is started.",
                "host":    "www.example.com",
                "tags": [
                  "web",
                  "example.com"
                ]
              }');
INSERT INTO logs
     VALUES ('{
                "message": "GET /",
                "host":    "www.example.com",
                "code":    200,
                "tags": [
                  "web",
                  "example.com"
                ]
              }');
INSERT INTO logs
     VALUES ('{
                "message": "Send to <info@example.com>.",
                "host":    "mail.example.net",
                "tags": [
                  "mail",
                  "example.net"
                ]
              }');

シーケンシャルスキャンを無効にします。

SET enable_seqscan = off;

マッチする例は次の通りです。

(読みやすくするためにPostgreSQL 9.5以降で使えるjsonb_pretty()関数を使っています。)

SELECT jsonb_pretty(record) FROM logs WHERE record @> '{"host": "www.example.com"}'::jsonb;
--             jsonb_pretty             
-- -------------------------------------
--  {                                  +
--      "host": "www.example.com",     +
--      "tags": [                      +
--          "web",                     +
--          "example.com"              +
--      ],                             +
--      "message": "Server is started."+
--  }
--  {                                  +
--      "code": 200,                   +
--      "host": "www.example.com",     +
--      "tags": [                      +
--          "web",                     +
--          "example.com"              +
--      ],                             +
--      "message": "GET /"             +
--  }
-- (2 rows)

マッチしない例は次の通りです。

検索条件のjsonb型の値で配列を使った場合、検索対象のjsonb型の値にすべての要素が含まれていなければいけません。要素の順番は問いません。もし、検索条件のjsonb型の値の要素のうち、1つでも検索対象のjsonb型の値に含まれていない要素があればそのレコードはマッチしません。

以下の例では、"mail"または"web"を含むレコードはありますが、"mail""web"両方を含むレコードはありません。そのため、次のSELECTは1つもレコードを返しません。

SELECT jsonb_pretty(record) FROM logs WHERE record @> '{"tags": ["mail", "web"]}'::jsonb;
--  jsonb_pretty 
-- --------------
-- (0 rows)

参考