F.24. jsquery
JsQuery â ÑÑо ÑзÑк запÑоÑов к даннÑм jsonb. Ðго оÑновное пÑедназнаÑение â пÑедоÑÑавиÑÑ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸ÑелÑнÑÑ ÑÑнкÑионалÑноÑÑÑ Ð´Ð»Ñ jsonb, напÑимеÑ, пÑоÑÑой и ÑÑÑекÑивнÑй ÑпоÑоб поиÑка во вложеннÑÑ
обÑекÑаÑ
и маÑÑиваÑ
, а Ñакже дополниÑелÑнÑе опеÑаÑоÑÑ ÑÑÐ°Ð²Ð½ÐµÐ½Ð¸Ñ Ñ Ð¿Ð¾Ð´Ð´ÐµÑжкой индекÑов.
JsQuery Ñеализован поÑÑедÑÑвом Ñипа даннÑÑ
jsquery (подобно tsquery) и опеÑаÑоÑа @@ Ð´Ð»Ñ Ð¿ÑÐ¸Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð·Ð°Ð¿ÑоÑов к jsonb.
F.24.1. УÑÑановка
ÐÑогÑаммнÑй ÐºÐ¾Ð¼Ð¿Ð»ÐµÐºÑ Postgres Pro Standard вклÑÑÐ°ÐµÑ jsquery в каÑеÑÑве дополниÑелÑного модÑÐ»Ñ (contrib). УÑÑановив Ð½ÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼Ñе компоненÑÑ Postgres Pro Standard, ÑоздайÑе ÑаÑÑиÑение jsquery ÑледÑÑÑим обÑазом:
CREATE EXTENSION jsquery;
F.24.2. ЯзÑк запÑоÑов JSON
РаÑÑиÑение JsQuery ÑодеÑÐ¶Ð¸Ñ Ñип jsquery, пÑедÑÑавлÑÑÑий веÑÑ Ð·Ð°Ð¿ÑÐ¾Ñ JSON в виде одного знаÑÐµÐ½Ð¸Ñ (как и tsquery Ð´Ð»Ñ Ð¿Ð¾Ð»Ð½Ð¾ÑекÑÑового поиÑка). Ð ÑÑом запÑоÑе задаÑÑÑÑ Ð²ÑÑажение, обÑаÑаÑÑееÑÑ Ðº докÑменÑам JSON.
ÐÑоÑÑое вÑÑажение запиÑÑваеÑÑÑ Ð² виде пÑÑÑ Ð±Ð¸Ð½Ð°ÑнÑй_опеÑаÑÐ¾Ñ Ð·Ð½Ð°Ñение или пÑÑÑ ÑнаÑнÑй_опеÑаÑоÑ. См. ÑледÑÑÑие пÑимеÑÑ.
x = "abc"â знаÑение клÑÑа "x" Ñавно "abc";$ @> [4, 5, "zzz"]â докÑÐ¼ÐµÐ½Ñ JSON пÑедÑÑавлÑÐµÑ Ñобой маÑÑив, ÑодеÑжаÑий знаÑÐµÐ½Ð¸Ñ 4, 5 и "zzz";"abc xyz" >= 10â знаÑение клÑÑа "abc xyz" болÑÑе или Ñавно 10;volume IS NUMERICâ клÑÑ Â«volume» Ð¸Ð¼ÐµÐµÑ ÑиÑловой Ñип.$ = trueâ веÑÑ Ð´Ð¾ÐºÑÐ¼ÐµÐ½Ñ JSON пÑедÑÑавлÑÐµÑ Ñобой пÑоÑÑо знаÑение true.similar_ids.@# > 5-similar_idsÑвлÑеÑÑÑ Ð¼Ð°ÑÑивом или обÑекÑом Ñ ÑиÑлом ÑлеменÑов болÑÑе 5;similar_product_ids.# = "0684824396"â маÑÑивsimilar_product_idsÑодеÑÐ¶Ð¸Ñ ÑÑÑÐ¾ÐºÑ "0684824396".*.color = "red"â внÑÑÑи докÑменÑа ÑÑÑеÑÑвÑÐµÑ Ð¾Ð±ÑекÑ, клÑÑ "color" в коÑоÑом Ð¸Ð¼ÐµÐµÑ Ð·Ð½Ð°Ñение "red".foo = *â в обÑекÑе ÑÑÑеÑÑвÑÐµÑ ÐºÐ»ÑÑ Â«foo».
ÐÑÑÑ Ð²ÑбиÑÐ°ÐµÑ Ð½Ð°Ð±Ð¾Ñ Ð·Ð½Ð°Ñений JSON Ð´Ð»Ñ Ð¿ÑовеÑки, иÑполÑзÑÑ Ð·Ð°Ð´Ð°Ð½Ð½Ñе опеÑаÑоÑÑ. РпÑоÑÑейÑем ÑлÑÑае пÑÑÑ â ÑÑо пÑоÑÑо Ð¸Ð¼Ñ ÐºÐ»ÑÑа. РобÑем ÑлÑÑае пÑÑÑ Ð·Ð°Ð´Ð°ÑÑ Ð¸Ð¼ÐµÐ½Ð° клÑÑей и подÑÑановоÑнÑе знаки, ÑоединÑннÑе ÑоÑками. ÐодÑÑановоÑнÑе знаки в пÑÑи могÑÑ Ð±ÑÑÑ ÑледÑÑÑими:
#â лÑбой ÑÐ»ÐµÐ¼ÐµÐ½Ñ Ð² маÑÑиве;#Nâ N-Ñй Ð¸Ð½Ð´ÐµÐºÑ Ð² маÑÑиве;%â лÑбой клÑÑ Ð¾Ð±ÑекÑа;*â лÑбой Ð½Ð°Ð±Ð¾Ñ ÑлеменÑов маÑÑивов и клÑÑей обÑекÑов;@#â длина маÑÑива или обÑекÑа, Ð¼Ð¾Ð¶ÐµÑ Ð·Ð°Ð´Ð°Ð²Ð°ÑÑÑÑ ÑолÑко в поÑледнем компоненÑе пÑÑи;$â веÑÑ Ð´Ð¾ÐºÑÐ¼ÐµÐ½Ñ JSON в виде одного знаÑениÑ, Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ ÑолÑко единÑÑвеннÑм компоненÑом пÑÑи.
РезÑлÑÑÐ°Ñ Ð²ÑÑÐ°Ð¶ÐµÐ½Ð¸Ñ â true, когда опеÑаÑÐ¾Ñ Ð²ÑдаÑÑ true как минимÑм Ð´Ð»Ñ Ð¾Ð´Ð½Ð¾Ð³Ð¾ знаÑениÑ, вÑбÑанного по Ð·Ð°Ð´Ð°Ð½Ð½Ð¾Ð¼Ñ Ð¿ÑÑи.
Ðмена клÑÑей могÑÑ Ð·Ð°Ð´Ð°Ð²Ð°ÑÑÑÑ Ð² двойнÑÑ ÐºÐ°Ð²ÑÑÐºÐ°Ñ Ð¸ без Ð½Ð¸Ñ . Ðмена клÑÑей без кавÑÑек не могÑÑ ÑодеÑжаÑÑ Ð¿ÑобелÑ, наÑинаÑÑÑÑ Ñ ÑиÑÑÑ Ð¸Ð»Ð¸ ÑовпадаÑÑ Ñ ÐºÐ»ÑÑевÑм Ñловом jsquery.
ÐоддеÑживаÑÑÑÑ ÑледÑÑÑие бинаÑнÑе опеÑаÑоÑÑ:
ÐпеÑаÑÐ¾Ñ ÑавенÑÑва:
=;ÐпеÑаÑоÑÑ ÑиÑленного ÑÑавнениÑ:
>,>=,<,<=;ÐпеÑаÑоÑ
INÐ´Ð»Ñ Ð¿Ð¾Ð¸Ñка в ÑпиÑке ÑкалÑÑнÑÑ Ð·Ð½Ð°Ñений;ÐпеÑаÑоÑÑ ÑÑÐ°Ð²Ð½ÐµÐ½Ð¸Ñ Ð¼Ð°ÑÑивов:
&&(пеÑеÑекаеÑÑÑ Ñ),@>(ÑодеÑжиÑ),<@(ÑодеÑжиÑÑÑ Ð²).ÐпеÑаÑÐ¾Ñ ÑилÑÑÑа:
~~. ÐÑÐ¸Ð½Ð¸Ð¼Ð°Ñ Ð´Ð°Ð½Ð½Ñеjsonbв каÑеÑÑве левого опеÑанда и вÑÑажениеjsqueryв каÑеÑÑве пÑавого, ÑÑÐ¾Ñ Ð¾Ð¿ÐµÑаÑÐ¾Ñ Ð¸ÑÐµÑ Ð² даннÑÑjsonbÑлеменÑÑ, ÑдовлеÑвоÑÑÑÑие ÑÑловиÑ, Ð·Ð°Ð´Ð°Ð½Ð½Ð¾Ð¼Ñ Ð² вÑÑаженииjsquery, и возвÑаÑÐ°ÐµÑ Ð¼Ð°ÑÑив ÑÐ°ÐºÐ¸Ñ ÑлеменÑов, еÑли они Ð½Ð°Ñ Ð¾Ð´ÑÑÑÑ.
ÐоддеÑживаÑÑÑÑ ÑледÑÑÑие ÑнаÑнÑе опеÑаÑоÑÑ:
ÐпеÑаÑÐ¾Ñ Ð¿ÑовеÑки ÑÑÑеÑÑвованиÑ:
= *;ÐпеÑаÑоÑÑ Ð¿ÑовеÑки Ñипа:
IS ARRAY,IS NUMERIC,IS OBJECT,IS STRINGиIS BOOLEAN.
ÐÑÑÐ°Ð¶ÐµÐ½Ð¸Ñ Ð¼Ð¾Ð³ÑÑ Ð±ÑÑÑ ÑложнÑми. Сложное вÑÑажение обÑазÑеÑÑÑ Ð½Ð°Ð±Ð¾Ñом вÑÑажений, ÑоединÑннÑÑ
логиÑеÑкими опеÑаÑоÑами (AND, OR и NOT) и ÑгÑÑппиÑованнÑÑ
Ñкобками.
ÐÑимеÑÑ ÑложнÑÑ Ð²ÑÑажений пÑÐ¸Ð²ÐµÐ´ÐµÐ½Ñ Ð½Ð¸Ð¶Ðµ.
a = 1 AND (b = 2 OR c = 3) AND NOT d = 1x.% = true OR x.# = true
ÐÑÑÑ Ð¼Ð¾Ð¶ÐµÑ Ð²ÐºÐ»ÑÑаÑÑ Ð² ÑÐµÐ±Ñ Ð¿ÑеÑикÑнÑе вÑÑÐ°Ð¶ÐµÐ½Ð¸Ñ (подвÑÑажениÑ). Ð ÑÑом ÑлÑÑае пÑÑÑ Ð²ÑбиÑÐ°ÐµÑ Ð·Ð½Ð°ÑÐµÐ½Ð¸Ñ JSON Ð´Ð»Ñ Ð¿ÑовеÑки по заданнÑм подвÑÑажениÑм. РезÑлÑÑаÑÑ Ð¿ÑовеÑки агÑегиÑÑÑÑÑÑ Ñак же, как и в пÑоÑÑÑÑ Ð²ÑÑажениÑÑ .
#(a = 1 AND b = 2)â маÑÑив ÑодеÑÐ¶Ð¸Ñ ÑлеменÑ, в коÑоÑом знаÑение клÑÑаaÑавно 2 и знаÑение клÑÑаbÑавно 2%($ >= 10 AND $ <= 20)â обÑÐµÐºÑ ÑодеÑÐ¶Ð¸Ñ ÐºÐ»ÑÑ Ñо знаÑением Ð¾Ñ 10 до 20
ÐÑÑÑ Ñакже Ð¼Ð¾Ð¶ÐµÑ ÑодеÑжаÑÑ ÑледÑÑÑие подÑÑановоÑнÑе знаки, обознаÑаÑÑие «каждÑй»:
#:â каждÑй Ð¸Ð½Ð´ÐµÐºÑ Ð² маÑÑиве;%:â каждÑй клÑÑ Ð¾Ð±ÑекÑа;*:â каждÑй ÑÐ»ÐµÐ¼ÐµÐ½Ñ Ð¼Ð°ÑÑива или клÑÑ Ð¾Ð±ÑекÑа.
РаÑÑмоÑÑим ÑледÑÑÑий пÑимеÑ.
%.#:($ >= 0 AND $ <= 1)
ÐÑо ÑÑловие можно пÑоÑиÑаÑÑ ÐºÐ°Ðº: ÑÑÑеÑÑвÑÐµÑ Ð¼Ð¸Ð½Ð¸Ð¼Ñм один клÑÑ, Ð´Ð»Ñ ÐºÐ¾ÑоÑого знаÑением ÑвлÑеÑÑÑ Ð¼Ð°ÑÑив ÑиÑел Ð¾Ñ 0 до 1.
ÐÑ Ð¼Ð¾Ð¶ÐµÐ¼ пеÑепиÑаÑÑ ÑÑÐ¾Ñ Ð¿ÑÐ¸Ð¼ÐµÑ Ð² ÑледÑÑÑей ÑоÑме Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸ÑелÑнÑми Ñкобками.
%(#:($ >= 0 AND $ <= 1))
ÐеÑвÑй подÑÑановоÑнÑй знак % пÑовеÑÑеÑ, ÑÑо вÑÑажение в ÑкобкаÑ
иÑÑинно как минимÑм Ð´Ð»Ñ Ð¾Ð´Ð½Ð¾Ð³Ð¾ знаÑÐµÐ½Ð¸Ñ Ð² обÑекÑе. ÐÑоÑой подÑÑановоÑнÑй знак #: пÑовеÑÑеÑ, ÑÑо знаÑение â маÑÑив, вÑе ÑлеменÑÑ ÐºÐ¾ÑоÑого ÑдовлеÑвоÑÑÑÑ ÑÑÐ»Ð¾Ð²Ð¸Ñ Ð² ÑкобкаÑ
.
ÐÑ Ð¼Ð¾Ð¶ÐµÐ¼ пеÑепиÑаÑÑ ÑÑÐ¾Ñ Ð¿ÑÐ¸Ð¼ÐµÑ Ð±ÐµÐ· подÑÑановоÑного знака #: ÑледÑÑÑим обÑазом.
%(NOT #(NOT ($ >= 0 AND $ <= 1)) AND $ IS ARRAY)
Ð ÑÑом пÑимеÑе Ð¼Ñ Ð¿ÑеобÑазÑем ÑÑвеÑждение, ÑÑо каждÑй ÑÐ»ÐµÐ¼ÐµÐ½Ñ Ð¼Ð°ÑÑива ÑдовлеÑвоÑÑÐµÑ Ð½ÐµÐºÐ¾ÑоÑÐ¾Ð¼Ñ ÑÑловиÑ, в ÑÑвеÑждение, ÑÑо ни один ÑÐ»ÐµÐ¼ÐµÐ½Ñ Ð½Ðµ ÑдовлеÑвоÑÑÐµÑ ÑÐ¾Ð¼Ñ Ð¶Ðµ ÑÑловиÑ.
Ðиже пÑÐ¸Ð²ÐµÐ´ÐµÐ½Ñ Ð¿ÑимеÑÑ Ð¸ÑполÑÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¿ÑÑей.
numbers.#: IS NUMERICâ каждÑй ÑÐ»ÐµÐ¼ÐµÐ½Ñ Ð¼Ð°ÑÑива numbers ÑвлÑеÑÑÑ ÑиÑлом.*:($ IS OBJECT OR $ IS BOOLEAN)â докÑÐ¼ÐµÐ½Ñ JSON пÑедÑÑавлÑÐµÑ Ñобой ÑÑÑÑкÑÑÑÑ Ð²Ð»Ð¾Ð¶ÐµÐ½Ð½ÑÑ Ð¾Ð±ÑекÑов, на ÑÑовне лиÑÑÑев ÑодеÑжаÑÑÑ Ð»Ð¾Ð³Ð¸ÑеÑкие знаÑениÑ.#:.%:($ >= 0 AND $ <= 1)â каждÑй ÑÐ»ÐµÐ¼ÐµÐ½Ñ Ð¼Ð°ÑÑива пÑедÑÑавлÑÐµÑ Ñобой обÑекÑ, ÑодеÑжаÑий ÑиÑловÑе знаÑÐµÐ½Ð¸Ñ Ð¾Ñ 0 до 1.documents.#:.% = *â клÑÑÑ documents ÑооÑвеÑÑÑвÑÐµÑ Ð¼Ð°ÑÑив из обÑекÑов, ÑодеÑжаÑÐ¸Ñ Ð¼Ð¸Ð½Ð¸Ð¼Ñм один клÑÑ.%.#: ($ IS STRING)â обÑÐµÐºÑ JSON ÑодеÑÐ¶Ð¸Ñ Ð¼Ð¸Ð½Ð¸Ð¼Ñм один маÑÑив Ñо ÑÑÑоками.#.% = trueâ как минимÑм один ÑÐ»ÐµÐ¼ÐµÐ½Ñ Ð¼Ð°ÑÑива ÑвлÑеÑÑÑ Ð¾Ð±ÑекÑом, ÑодеÑжаÑим минимÑм одно знаÑение true.
ÐÑполÑзование опеÑаÑоÑов пÑÑи и Ñкобок ÑÑебÑÐµÑ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸ÑелÑнÑÑ
ÑазÑÑÑнений. Ðогда опеÑаÑоÑÑ Ð¿ÑÑи иÑполÑзÑÑÑÑÑ Ð½ÐµÐ¾Ð´Ð½Ð¾ÐºÑаÑно, они могÑÑ ÑÑÑлаÑÑÑÑ Ð½Ð° ÑазлиÑнÑе знаÑениÑ, Ñогда как, иÑполÑзÑÑ Ñкобки и опеÑаÑÐ¾Ñ $, Ð²Ñ Ð±ÑдеÑе многокÑаÑно обÑаÑаÑÑÑÑ Ðº Ð¾Ð´Ð½Ð¾Ð¼Ñ Ð·Ð½Ð°ÑениÑ. ÐзглÑниÑе на ÑледÑÑÑие пÑимеÑÑ.
# < 10 AND # > 20â ÑÑÑеÑÑвÑÐµÑ ÑÐ»ÐµÐ¼ÐµÐ½Ñ Ð¼ÐµÐ½ÑÑе 10 и ÑÑÑеÑÑвÑÐµÑ Ð´ÑÑгой ÑÐ»ÐµÐ¼ÐµÐ½Ñ Ð±Ð¾Ð»ÑÑе 20.#($ < 10 AND $ > 20)â ÑÑÑеÑÑвÑÐµÑ ÑлеменÑ, коÑоÑÑй одновÑеменно менÑÑе 10 и болÑÑе 20 (ÑÑо невозможно).#($ >= 10 AND $ <= 20)â ÑÑÑеÑÑвÑÐµÑ ÑÐ»ÐµÐ¼ÐµÐ½Ñ Ð¼ÐµÐ¶Ð´Ñ 10 и 20.# >= 10 AND # <= 20â ÑÑÑеÑÑвÑÐµÑ ÑлеменÑ, болÑÑий или ÑавнÑй 10, и дÑÑгой ÑлеменÑ, менÑÑий или ÑавнÑй 20. ÐапÑÐ¾Ñ Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ ÑдовлеÑвоÑÑн маÑÑивом без ÑлеменÑов Ð¼ÐµÐ¶Ð´Ñ 10 и 20, напÑÐ¸Ð¼ÐµÑ [0,30].
Те же пÑавила пÑименÑÑÑÑÑ Ð¿Ñи поиÑке внÑÑÑи обÑекÑов и веÑвей.
ÐпеÑаÑоÑÑ Ð¿ÑовеÑки Ñипа и подÑÑановоÑнÑе знаки «каждÑй» Ð¿Ð¾Ð»ÐµÐ·Ð½Ñ Ð´Ð»Ñ Ð¿ÑовеÑки пÑавилÑноÑÑи ÑÑ
ÐµÐ¼Ñ Ð´Ð¾ÐºÑменÑа. ÐпеÑаÑÐ¾Ñ ÑопоÑÑÐ°Ð²Ð»ÐµÐ½Ð¸Ñ JsQuery @@ ÑвлÑеÑÑÑ Ð¿Ð¾ÑÑоÑннÑм (IMMUTABLE) и Ð¼Ð¾Ð¶ÐµÑ Ð¿ÑименÑÑÑÑÑ Ð² огÑаниÑениÑÑ
CHECK. ÐзглÑниÑе на ÑледÑÑÑий пÑимеÑ.
CREATE TABLE js (
id serial,
data jsonb,
CHECK (data @@ '
name IS STRING AND
similar_ids.#: IS NUMERIC AND
points.#:(x IS NUMERIC AND y IS NUMERIC)'::jsquery));Ð ÑÑом пÑимеÑе огÑаниÑение-пÑовеÑка конÑÑолиÑÑÐµÑ Ð´Ð°Ð½Ð½Ñе в колонке data Ñипа jsonb: знаÑением клÑÑа name должна бÑÑÑ ÑÑÑока, знаÑением клÑÑа similar_ids â маÑÑив ÑиÑел, знаÑением клÑÑа points â маÑÑив обÑекÑов, ÑодеÑжаÑÐ¸Ñ ÑиÑловÑе знаÑÐµÐ½Ð¸Ñ Ð´Ð»Ñ ÐºÐ»ÑÑей x и y.
ÐÑÑгие пÑимеÑÑ Ð¼Ð¾Ð¶Ð½Ð¾ найÑи в наÑей пÑезенÑаÑии Ð´Ð»Ñ pgconf.eu.
F.24.3. ÐндекÑÑ GIN
РаÑÑиÑение JsQuery ÑодеÑÐ¶Ð¸Ñ Ð´Ð²Ð° клаÑÑа опеÑаÑоÑов Ð´Ð»Ñ GIN, коÑоÑÑе ÑеализÑÑÑ ÑазлиÑнÑе ваÑианÑÑ Ð¾Ð¿ÑимизаÑии запÑоÑов.
jsonb_path_value_ops
jsonb_value_path_ops
Ð ÑÑÐ¸Ñ ÐºÐ»Ð°ÑÑÐ°Ñ GIN докÑменÑÑ jsonb ÑаÑкладÑваÑÑÑÑ Ð½Ð° ÑлеменÑÑ. ÐаждÑй ÑÐ»ÐµÐ¼ÐµÐ½Ñ ÑопоÑÑавлÑеÑÑÑ Ñ Ð¾Ð¿ÑеделÑннÑм знаÑением и Ñвоим пÑÑÑм. РазлиÑаÑÑÑÑ ÑÑи клаÑÑÑ Ð¾Ð¿ÐµÑаÑоÑов Ñем, как в Ð½Ð¸Ñ Ð¿ÑедÑÑÐ°Ð²Ð»ÐµÐ½Ñ ÑлеменÑÑ, как они ÑÑавниваÑÑÑÑ Ð¸ иÑполÑзÑÑÑÑÑ Ð´Ð»Ñ Ð¾Ð¿ÑимизаÑии поиÑка.
ÐапÑимеÑ, докÑÐ¼ÐµÐ½Ñ jsonb {"a": [{"b": "xyz", "c": true}, 10], "d": {"e": [7, false]}} бÑÐ´ÐµÑ Ñазложен на ÑледÑÑÑие ÑлеменÑÑ:
"a".#."b"."xyz""a".#."c".true"a".#.10"d"."e".#.7"d"."e".#.false
Так как JsQuery не поддеÑÐ¶Ð¸Ð²Ð°ÐµÑ Ð¿Ð¾Ð¸Ñк в опÑеделÑнном ÑлеменÑе маÑÑива, Ð¼Ñ ÑаÑÑмаÑÑиваем вÑе ÑлеменÑÑ Ð¼Ð°ÑÑива как одинаковÑе. Таким обÑазом, вÑе ÑлеменÑÑ Ð¼Ð°ÑÑива помеÑаÑÑÑÑ Ð¾Ð´Ð¸Ð½Ð°ÐºÐ¾Ð²Ñм знаком # в пÑÑи.
ÐÑновной пÑоблемой Ñакого пÑедÑÑÐ°Ð²Ð»ÐµÐ½Ð¸Ñ ÑлеменÑов ÑвлÑеÑÑÑ ÐµÐ³Ð¾ ÑазмеÑ. Так, в показанном пÑимеÑе клÑÑ Â«a» пÑиÑÑÑÑÑвÑÐµÑ ÑÑи Ñаза. РболÑÑом докÑменÑе Ñо множеÑÑвом веÑвей и длиннÑми клÑÑами ÑÐ°Ð·Ð¼ÐµÑ Ñакого наивного пÑедÑÑÐ°Ð²Ð»ÐµÐ½Ð¸Ñ ÑлеменÑов вÑÑ Ð¾Ð´Ð¸Ñ Ð·Ð° Ñамки ÑазÑмного. ÐÑи два клаÑÑа опеÑаÑоÑов ÑеÑаÑÑ ÑÑÑ Ð¿ÑоблемÑ, но Ñ Ð½ÐµÐºÐ¾ÑоÑÑми ÑазлиÑиÑми.
F.24.3.1. jsonb_path_value_ops
ÐлаÑÑ jsonb_path_value_ops пÑедÑÑавлÑÐµÑ ÑÐ»ÐµÐ¼ÐµÐ½Ñ Ð² виде паÑÑ Ñ ÐµÑа пÑÑи и знаÑениÑ. ÐÑо иллÑÑÑÑиÑÑÐµÑ ÑледÑÑÑий пÑевдокод.
(hash(ÑлеменÑ_пÑÑи_1.ÑлеменÑ_пÑÑи_2. ... .ÑлеменÑ_пÑÑи_n); знаÑение)
ÐÑи ÑÑавнении запиÑей Ñ ÐµÑ Ð¿ÑÑи ÑвлÑеÑÑÑ ÑÑаÑÑей ÑаÑÑÑÑ Ð·Ð°Ð¿Ð¸Ñи, а знаÑение â младÑей. ÐÑо опÑеделÑÐµÑ Ñ Ð°ÑакÑеÑиÑÑики данного клаÑÑа опеÑаÑоÑов. Так как пÑÑÑ Ñ ÐµÑиÑÑеÑÑÑ Ð¸ оказÑваеÑÑÑ Ð² веÑÑ Ð½ÐµÐ¹ ÑаÑÑи запиÑи, нам нÑжно знаÑÑ Ð¿Ð¾Ð»Ð½Ñй пÑÑÑ Ðº знаÑениÑ, ÑÑÐ¾Ð±Ñ Ð¸ÑполÑзоваÑÑ ÐµÐ³Ð¾ Ð´Ð»Ñ Ð¿Ð¾Ð¸Ñка. Ðднако еÑли пÑÑÑ Ð¸Ð·Ð²ÐµÑÑен, Ð¼Ñ Ð¼Ð¾Ð¶ÐµÐ¼ пÑименÑÑÑ Ð¸ ÑоÑнÑй поиÑк, и поиÑк знаÑений в инÑеÑвале.
F.24.3.2. jsonb_value_path_ops
ÐлаÑÑ jsonb_value_path_ops пÑедÑÑавлÑÐµÑ ÑÐ»ÐµÐ¼ÐµÐ½Ñ Ð² виде паÑÑ Ð·Ð½Ð°ÑÐµÐ½Ð¸Ñ Ð¸ ÑилÑÑÑа ÐлÑма Ð´Ð»Ñ Ð¿ÑÑи.
(знаÑение; bloom(ÑлеменÑ_пÑÑи_1) | bloom(ÑлеменÑ_пÑÑи_2) | ... | bloom(ÑлеменÑ_пÑÑи_n))
ÐÑи ÑÑавнении запиÑей знаÑение ÑвлÑеÑÑÑ ÑÑаÑÑей ÑаÑÑÑÑ Ð·Ð°Ð¿Ð¸Ñи, а ÑилÑÑÑ ÐлÑма Ð´Ð»Ñ Ð¿ÑÑи â младÑей. ÐÑо опÑеделÑÐµÑ Ñ
аÑакÑеÑиÑÑики данного клаÑÑа опеÑаÑоÑов. Так как знаÑение наÑ
одиÑÑÑ Ð² ÑÑаÑÑей ÑаÑÑи, Ð¼Ñ Ð¼Ð¾Ð¶ÐµÐ¼ вÑполнÑÑÑ Ð¾ÑÐµÐ½Ñ ÑÑÑекÑивно ÑолÑко поиÑк ÑоÑного знаÑениÑ. ÐоиÑк знаÑений в инÑеÑвале возможен, но Ð´Ð»Ñ ÑÑого пÑидÑÑÑÑ Ð¾ÑÑилÑÑÑоваÑÑ Ð²Ñе дÑÑгие пÑÑи, в коÑоÑÑÑ
бÑдÑÑ Ð½Ð°Ð¹Ð´ÐµÐ½Ñ Ð¿Ð¾Ð´Ñ
одÑÑие знаÑениÑ. ФилÑÑÑ ÐлÑма по ÑлеменÑам пÑÑи позволÑÐµÑ Ð¸ÑполÑзоваÑÑ Ð¸Ð½Ð´ÐµÐºÑ Ð´Ð»Ñ ÑÑловий, ÑодеÑжаÑиÑ
в пÑÑÑÑ
% и *.
F.24.3.3. ÐпÑимизаÑÐ¸Ñ Ð·Ð°Ð¿ÑоÑов
ÐлаÑÑÑ Ð¾Ð¿ÐµÑаÑоÑов JsQuery вÑполнÑÑÑ ÑложнÑÑ Ð¾Ð¿ÑимизаÑÐ¸Ñ Ð·Ð°Ð¿ÑоÑов. ÐÐ»Ñ ÑазÑабоÑÑика или админиÑÑÑаÑоÑа оÑÐµÐ½Ñ Ñенно имеÑÑ Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾ÑÑÑ Ð²Ð¸Ð´ÐµÑÑ ÑезÑлÑÑаÑÑ Ñакой опÑимизаÑии. Ðо к ÑожалениÑ, клаÑÑÑ Ð¾Ð¿ÐµÑаÑоÑов не могÑÑ Ð´Ð¾Ð±Ð°Ð²Ð»ÑÑÑ ÑÑо-либо ÑÐ²Ð¾Ñ Ð² вÑвод EXPLAIN. Ðменно поÑÑÐ¾Ð¼Ñ JsQuery пÑедоÑÑавлÑÐµÑ ÑледÑÑÑие ÑÑнкÑии, позволÑÑÑие ÑвидеÑÑ, как конкÑеÑнÑй клаÑÑ Ð¾Ð¿ÐµÑаÑоÑов опÑимизиÑÑÐµÑ Ð·Ð°Ð´Ð°Ð½Ð½Ñй запÑоÑ.
gin_debug_query_path_value(jsquery) â Ð´Ð»Ñ jsonb_path_value_ops
gin_debug_query_value_path(jsquery) â Ð´Ð»Ñ jsonb_value_path_ops
ÐÑи ÑÑнкÑии вÑдаÑÑ ÑекÑÑовое пÑедÑÑавление деÑева запÑоÑов, лиÑÑÑÑми в коÑоÑом ÑвлÑÑÑÑÑ Ð·Ð°Ð¿Ð¸Ñи, иÑкомÑе в индекÑе GIN. СледÑÑÑие пÑимеÑÑ Ð¿Ð¾ÐºÐ°Ð·ÑваÑÑ ÑазлиÑÐ¸Ñ Ð² ÑезÑлÑÑаÑÐ°Ñ Ð¾Ð¿ÑимизаÑии запÑоÑов Ð´Ð»Ñ ÑазнÑÑ ÐºÐ»Ð°ÑÑов опеÑаÑоÑов.
# SELECT gin_debug_query_path_value('x = 1 AND (*.y = 1 OR y = 2)');
gin_debug_query_path_value
----------------------------
x = 1 , entry 0 +
# SELECT gin_debug_query_value_path('x = 1 AND (*.y = 1 OR y = 2)');
gin_debug_query_value_path
----------------------------
AND +
x = 1 , entry 0 +
OR +
*.y = 1 , entry 1 +
y = 2 , entry 2 +Ð ÑожалениÑ, Ð´Ð»Ñ jsonb еÑÑ Ð½ÐµÑ ÑÑаÑиÑÑики. ÐÐ¾Ñ Ð¿Ð¾ÑÐµÐ¼Ñ Ð¾Ð¿ÑимизаÑÐ¾Ñ JsQuery должен пÑинимаÑÑ Ð¸Ð¼Ð¿ÐµÑаÑивнÑе ÑеÑениÑ, вÑбиÑÐ°Ñ ÑÑловиÑ, обÑабаÑÑваемÑе Ñ Ð¸Ð½Ð´ÐµÐºÑом. ÐÑи ÑÑом он ÑÑководÑÑвÑеÑÑÑ Ð¿Ñедположением, ÑÑо некоÑоÑÑе ÑÐ¸Ð¿Ñ ÑÑловий ÑвлÑÑÑÑÑ Ð¼ÐµÐ½ÐµÐµ избиÑаÑелÑнÑми, Ñем дÑÑгие. Таким обÑазом, опÑимизаÑÐ¾Ñ ÑазделÑÐµÑ ÑÑÐ»Ð¾Ð²Ð¸Ñ Ð½Ð° ÑледÑÑÑие каÑегоÑии избиÑаÑелÑноÑÑи (пеÑеÑиÑленнÑе по ÑбÑÐ²Ð°Ð½Ð¸Ñ Ð¸Ð·Ð±Ð¸ÑаÑелÑноÑÑи).
РавнÑеÑÑÑ (x = c)
РинÑеÑвале (c1 < x < c2)
Ðе ÑавнÑеÑÑÑ (x > c)
ЯвлÑеÑÑÑ (x is type)
ÐÑбое (x = *)
ÐпÑимизаÑÐ¾Ñ Ð¸Ð·Ð±ÐµÐ³Ð°ÐµÑ Ð¸ÑполÑÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¸Ð½Ð´ÐµÐºÑа Ð´Ð»Ñ Ð¼ÐµÐ½ÐµÐµ избиÑаÑелÑнÑÑ
ÑÑловий, когда ÑÑо возможно. ÐапÑимеÑ, в запÑоÑе x = 1 AND y > 0 ÑÑловие x = 1 ÑÑиÑаеÑÑÑ Ð±Ð¾Ð»ÐµÐµ избиÑаÑелÑнÑм, Ñем y > 0. ÐоÑÑÐ¾Ð¼Ñ Ð´Ð»Ñ Ð²ÑÑиÑÐ»ÐµÐ½Ð¸Ñ y > 0 Ð¸Ð½Ð´ÐµÐºÑ Ð½Ðµ иÑполÑзÑеÑÑÑ.
# SELECT gin_debug_query_path_value('x = 1 AND y > 0');
gin_debug_query_path_value
----------------------------
x = 1 , entry 0 +РеÑениÑ, пÑинимаемÑе опÑимизаÑоÑом без ÑÑÑÑа ÑÑаÑиÑÑики, могÑÑ Ð±ÑÑÑ Ð½ÐµÑоÑнÑми. ÐоÑÑÐ¾Ð¼Ñ Ð² JsQuery поддеÑживаÑÑÑÑ Ð¿Ð¾Ð´Ñказки. ÐомменÑаÑии /*-- index */ и /*-- noindex */, помеÑÑннÑе в ÑÑловиÑ, ÑказÑваÑÑ Ð¾Ð¿ÑимизаÑоÑÑ ÑооÑвеÑÑÑвенно иÑполÑзоваÑÑ Ð¸Ð»Ð¸ не иÑполÑзоваÑÑ Ð¸Ð½Ð´ÐµÐºÑ.
SELECT gin_debug_query_path_value('x = 1 AND y /*-- index */ > 0');
gin_debug_query_path_value
----------------------------
AND +
x = 1 , entry 0 +
y > 0 , entry 1 +
SELECT gin_debug_query_path_value('x /*-- noindex */ = 1 AND y > 0');
gin_debug_query_path_value
----------------------------
y > 0 , entry 0 +F.24.4. ÐвÑоÑÑ
ФÑÐ´Ð¾Ñ Ð¡Ð¸Ð³Ð°ÐµÐ²
<teodor@sigaev.ru>, Postgres Professional, ÐоÑква, РоÑÑиÑÐлекÑÐ°Ð½Ð´Ñ ÐоÑоÑков
<aekorotkov@gmail.com>, Postgres Professional, ÐоÑква, РоÑÑиÑÐлег ÐаÑÑÑнов
<oleg@sai.msu.su>, Postgres Professional, ÐоÑква, РоÑÑиÑ
F.24.5. ÐлагодаÑноÑÑи
ÐÑ Ð²ÑÑажаем пÑизнаÑелÑноÑÑÑ ÑпонÑоÑÑ ÑазÑабоÑки, компании Wargaming.net.