This is a document for PGroonga 2.0.0 or later. See PGroonga 1.X document when you're using PGroonga 1.X.
@@ operator for jsonb typeThis operator is deprecated since 1.2.1. Use &` operator instead.
@@ operator is a PGroonga original operator. You can use complex condition that can't be written by @> operator such as range search.
If you know JsQuery, you can understand like "PGroonga provides jsonb type related search features that are similar to JsQuery with different syntax".
Here is the syntax of this operator:
jsonb_column @@ condition
jsonb_column is a column that its type is jsonb.
condition is a text value used as query. It uses [Groonga's script syntax][groogna-script-syntax].
The operator returns true when condition matches jsonb_column value, false otherwise.
You need to specify one of the following operator classes to use this operator:
pgroonga_jsonb_ops_v2: Default for jsonb
pgroonga_jsonb_ops: For jsonb
Here are sample schema and data for examples:
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"
]
}');
Disable sequential scan:
SET enable_seqscan = off;
You need to understand how PGroonga creates index against jsonb type value to create search condition.
PGroonga splits a jsonb type value into values and then creates indexes against these values. In SQL, think about the following schema:
CREATE TABLE values (
key text PRIMARY KEY,
path text,
paths text[],
type text,
boolean boolean,
number double precision,
string text,
size numeric
);
Here are descriptions of column:
key: The ID of the value. If value has the same path and content, key is the same value. Key format is '${PATH}|${TYPE}|${VALUE}'. It's not used in search condition.
path: The path of the value from root. It uses jq compatible format. Object is ["${ELEMENT_NAME}"], array is []. For example, the path of "web" in {"tags": ["web"]} is .["tags"][]. If you know absolute path of the value, you can use this value in search condition.
paths: The paths of the value. It includes absolute path, sub paths, .${ELEMENT_NAME1}.${ELEMENT_NAME2} format paths and paths without array. This column is convenient for search condition because you can use one of them for search condition. Here are paths for "x" in {"a": {"b": "c": ["x"]}}:
.a.b.c.["a"]["b"]["c"].["a"]["b"]["c"][]a.b.c["a"]["b"]["c"]["a"]["b"]["c"][]b.c["b"]["c"]["b"]["c"][]c["c"]["c"][][]type: The type of the value. This column value is one of them:
"object": Object. No value.
"array": Array. The number of elements is stored in size column.
"boolean": Boolean. The value is stored in boolean column.
"number": Number. The value is stored in number column.
"string": String. The value is stored in string column.
boolean: The value if type column value is "boolean", false otherwise.
number: The value if type column value is "number", 0 otherwise.
string: The value if type column value is "string", "" otherwise.
size: The number of elements if type column value is "array", 0 otherwise.
Here is a sample JSON:
{
"message": "GET /",
"host": "www.example.com",
"code": 200,
"tags": [
"web",
"example.com"
]
}
The JSON is split to the following values. (They are part of all split values.)
| key | path | paths | type | boolean | number | string | size |
|---|---|---|---|---|---|---|---|
.|object |
. |
[.] |
object |
||||
.["message"]|string|GET / |
.["message"] |
[.message, .["message"], message, ["message"]] |
string |
GET / |
|||
.["tags"][]|string|web |
.["tags"] |
[.tags, .["tags"], .["tags"][], tags, ["tags"], ["tags"][], []] |
string |
web |
You specify condition that matches split value to @@ operator. If there is one or more split values that match specified condition in jsonb type value, the jsonb type value is matched.
Here is a condition that searches jsonb type value that has www.example.com string:
(It uses jsonb_pretty() function provided since PostgreSQL 9.5 for readability.)
SELECT jsonb_pretty(record) FROM logs WHERE record @@ 'string == "www.example.com"';
-- 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)
Here is a condition that searches jsonb type value that has number between 200 to 299 as code column value. The condition uses paths @ "..." syntax to use simple path format (.code) to specify path.
SELECT jsonb_pretty(record) FROM logs WHERE record @@ 'paths @ ".code" && number >= 200 && number < 300';
-- jsonb_pretty
-- --------------------------------
-- { +
-- "code": 200, +
-- "host": "www.example.com",+
-- "tags": [ +
-- "web", +
-- "example.com" +
-- ], +
-- "message": "GET /" +
-- }
-- (1 row)
Here is a condition for full text search from all text values in jsonb value type:
SELECT jsonb_pretty(record) FROM logs WHERE record @@ 'string @ "started"';
-- jsonb_pretty
-- -------------------------------------
-- { +
-- "host": "www.example.com", +
-- "tags": [ +
-- "web", +
-- "example.com" +
-- ], +
-- "message": "Server is started."+
-- }
-- (1 row)
You can use Groonga's query syntax (a OR b can be used) for full text search by query("string", "...") syntax:
SELECT jsonb_pretty(record) FROM logs WHERE record @@ 'query("string", "send OR server")';
-- jsonb_pretty
-- ----------------------------------------------
-- { +
-- "host": "www.example.com", +
-- "tags": [ +
-- "web", +
-- "example.com" +
-- ], +
-- "message": "Server is started." +
-- }
-- { +
-- "host": "mail.example.net", +
-- "tags": [ +
-- "mail", +
-- "example.net" +
-- ], +
-- "message": "Send to <info@example.com>."+
-- }
-- (2 rows)
@> operator: Search by a jsonb data
&` operator: Advanced search by ECMAScript like query language