рдХреНрдпрд╛ рд╕реБрд╡рд┐рдзрд╛ рдлреНрд░реАрдЬ 2019 рдкрд░ рдЬрдореА рдереАред рднрд╛рдЧ I JSONPath


2019-03 рд╕рдорд┐рддрд┐рдпреЛрдВ рдХреЗ рдмрд╛рдж, рд╕реБрд╡рд┐рдзрд╛ рдлреНрд░реАрдЬ рд╣реБрдИред рд╣рдорд╛рд░реЗ рдпрд╣рд╛рдВ рд▓рдЧрднрдЧ рдПрдХ рдкрд╛рд░рдВрдкрд░рд┐рдХ рдХреЙрд▓рдо рд╣реИ: рд╣рдордиреЗ рдкрд╣рд▓реЗ рд╣реА рдкрд┐рдЫрд▓реЗ рд╕рд╛рд▓ рдХреЗ рдлреНрд░реАрдЬ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд▓рд┐рдЦрд╛ рдерд╛ ред рдЕрдм, 2019 рдХреЗ рдкрд░рд┐рдгрд╛рдо: рдХреМрди рд╕реЗ рдирдП рдХреЛ PostgreSQL 12. рдореЗрдВ рд╢рд╛рдорд┐рд▓ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, JSONPath рдХреЛ рд╕рдорд░реНрдкрд┐рдд рд╕рдореАрдХреНрд╖рд╛ рдХреЗ рдЗрд╕ рднрд╛рдЧ рдореЗрдВ, "рдкреЛрд╕реНрдЯрдЧреНрд░реВрдЬ 12 рдЗрди рдПрдЯреНрд░реНрдпреВрдбреНрд╕" рд░рд┐рдкреЛрд░реНрдЯ рд╕реЗ рдЙрджрд╛рд╣рд░рдг рдФрд░ рдЯреБрдХрдбрд╝реЗ, рдЬреЛ рдХрд┐ рдУрд▓реЗрдЧ рдмрд╛рд░реНрдЯреБрдиреЛрд╡ рдиреЗ рд╕реЗрдВрдЯ рдкреАрдЯрд░реНрд╕рдмрд░реНрдЧ рдореЗрдВ рд╕реЗрдВрдЯ рд╣рд╛рдЗрд▓реЛрдб ++ рдореЗрдВ рдЗрд╕ рд╕рд╛рд▓ 9 рдЕрдкреНрд░реИрд▓ рдХреЛ рдкрдврд╝рд╛ рд╣реИ, рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

JSONPath


JSON (B) рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рд╕рдм рдХреБрдЫ рдкреНрд░рд╛рд╕рдВрдЧрд┐рдХ рд╣реИ, рджреБрдирд┐рдпрд╛ рдореЗрдВ, рд░реВрд╕ рдореЗрдВ рдорд╛рдВрдЧ рдореЗрдВ, рдФрд░ рдпрд╣ Postgres Professional рдореЗрдВ рд╡рд┐рдХрд╛рд╕ рдХреЗ рд╕рдмрд╕реЗ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдХреНрд╖реЗрддреНрд░реЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рд╣реИред JSON / JSONB рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП jsonb рдкреНрд░рдХрд╛рд░, рдлрд╝рдВрдХреНрд╢рдВрд╕ рдФрд░ рдСрдкрд░реЗрдЯрд░ PostgreSQL рд╕рдВрд╕реНрдХрд░рдг 9.4 рдореЗрдВ рджрд┐рдЦрд╛рдИ рджрд┐рдП, рд╡реЗ рдУрд▓реЗрдЧ рдмрд╛рд░реНрдЯреБрдиреЛрд╡ рдХреЗ рдиреЗрддреГрддреНрд╡ рдореЗрдВ рдПрдХ рдЯреАрдо рджреНрд╡рд╛рд░рд╛ рдХрд┐рдП рдЧрдП рдереЗред

JSON рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП SQL / 2016 рдорд╛рдирдХ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ: JSONPath рдХрд╛ рдЙрд▓реНрд▓реЗрдЦ рд╡рд╣рд╛рдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ - JSON рдХреЗ рдЕрдВрджрд░ рдбреЗрдЯрд╛ рдПрдбреНрд░реЗрд╕рд┐рдВрдЧ рдЯреВрд▓ рдХрд╛ рдПрдХ рд╕реЗрдЯ; JSONTABLE - JSON рдХреЛ рдирд┐рдпрдорд┐рдд рддрд╛рд▓рд┐рдХрд╛рдУрдВ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░рдиреЗ рдХрд╛ рд╕рд╛рдзрди; рдХрд╛рд░реНрдпреЛрдВ рдФрд░ рдСрдкрд░реЗрдЯрд░реЛрдВ рдХрд╛ рдПрдХ рдмрдбрд╝рд╛ рдкрд░рд┐рд╡рд╛рд░ред рдЗрд╕ рддрдереНрдп рдХреЗ рдмрд╛рд╡рдЬреВрдж рдХрд┐ рдкреЛрд╕реНрдЯрд╕рди рдореЗрдВ рдЬреЗрдиреНрд╕рди рдХреЛ рд▓рдВрдмреЗ рд╕рдордп рд╕реЗ рд╕рдорд░реНрдерди рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, 2017 рдореЗрдВ рдУрд▓реЗрдЧ рдмрд╛рд░реНрдЯреБрдиреЛрд╡ рдФрд░ рдЙрдирдХреЗ рд╕рд╣рдпреЛрдЧрд┐рдпреЛрдВ рдиреЗ рдорд╛рдирдХ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рдиреЗ рдкрд░ рдХрд╛рдо рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░ рджрд┐рдпрд╛ред рдорд╛рдирдХ рдХреЗ рд╕рд╛рде рдЕрдиреБрдкрд╛рд▓рди рд╣рдореЗрд╢рд╛ рдЕрдЪреНрдЫрд╛ рд╣реЛрддрд╛ рд╣реИред рдорд╛рдирдХ рдореЗрдВ рд╡рд░реНрдгрд┐рдд рд╕рднреА рдореЗрдВ рд╕реЗ, рдХреЗрд╡рд▓ рдПрдХ рд▓реЗрдХрд┐рди рд╕рдмрд╕реЗ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдкреИрдЪ 12 рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ JSONPath рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╣рдо рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдкрд╣рд▓реЗ рд╕реНрдерд╛рди рдкрд░ рдмрд╛рдд рдХрд░реЗрдВрдЧреЗред

рдкреНрд░рд╛рдЪреАрди рд╕рдордп рдореЗрдВ, рд▓реЛрдЧ JSON рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рдереЗ, рдЗрд╕реЗ рдкрд╛рда рдХреНрд╖реЗрддреНрд░реЛрдВ рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рддреЗ рдереЗред 9.3 рдореЗрдВ, JSON рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд┐рд╢реЗрд╖ рдбреЗрдЯрд╛ рдкреНрд░рдХрд╛рд░ рджрд┐рдЦрд╛рдИ рджрд┐рдпрд╛, рд▓реЗрдХрд┐рди рдЗрд╕рдХреЗ рд╕рд╛рде рдЬреБрдбрд╝реА рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рд╕рдореГрджреНрдз рдирд╣реАрдВ рдереА, рдФрд░ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдХреЗ рд╕рд╛рде рдЕрдиреБрд░реЛрдзреЛрдВ рдиреЗ JSON рдХреЗ рдкрд╛рда рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░рдиреЗ рдореЗрдВ рд▓рдЧрдиреЗ рд╡рд╛рд▓реЗ рд╕рдордп рдХреЗ рдХрд╛рд░рдг рдзреАрд░реЗ-рдзреАрд░реЗ рдХрд╛рдо рдХрд┐рдпрд╛ред рдЗрд╕рдиреЗ рдХрдИ рд╕рдВрднрд╛рд╡рд┐рдд рдкреЛрд╕реНрдЯрдЧреНрд░реЗрдЬ рдпреВрдЬрд░реНрд╕ рдХреЛ рд░реЛрдХ рджрд┐рдпрд╛, рдЬрд┐рдиреНрд╣реЛрдВрдиреЗ NoSQL рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЛ рдкреНрд░рд╛рдердорд┐рдХрддрд╛ рджреАред O. рдмрд╛рд░реНрдЯреБрдиреЛрд╡, рдПред рдХреЛрд░реЛрдЯрдХреЛрд╡ рдФрд░ рдПрдлред рд╕рд┐рдЧреЗрд╡ рдХреА рдмрджреМрд▓рдд рдкреЛрд╕реНрдЯрдЧреНрд░реИрдЬ рдЙрддреНрдкрд╛рджрдХрддрд╛ рдореЗрдВ 9.4 рдХреА рд╡реГрджреНрдзрд┐ рд╣реБрдИ, рдкреЛрд╕реНрдЯрдЧреНрд░реЗрдЬ рдиреЗ JSON - рдмрд╛рдЗрд╕рди рдкреНрд░рдХрд╛рд░ рдХрд╛ рдмрд╛рдЗрдирд░реА рд╕рдВрд╕реНрдХрд░рдг рдкреЗрд╢ рдХрд┐рдпрд╛ред
jsonb рдХреЛ рд╣рд░ рдмрд╛рд░ рдкрд╛рд░реНрд╕ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реЛрддреА рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЗрд╕рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдирд╛ рдЬреНрдпрд╛рджрд╛ рддреЗрдЬ рд╣реЛрддрд╛ рд╣реИред рдПрдХ рд╣реА рд╕рдордп рдореЗрдВ рдЙрддреНрдкрдиреНрди рд╣реЛрдиреЗ рд╡рд╛рд▓реЗ рдирдП рдХрд╛рд░реНрдпреЛрдВ рдФрд░ рдСрдкрд░реЗрдЯрд░реЛрдВ рдореЗрдВ рд╕реЗ, рдХреБрдЫ рдХреЗрд╡рд▓ рдПрдХ рдирдП, рджреНрд╡рд┐рдЖрдзрд╛рд░реА рдкреНрд░рдХрд╛рд░ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВ, рдЬреИрд╕реЗ рдХрд┐ рдШрдЯрдирд╛ рдХреЗ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдСрдкрд░реЗрдЯрд░ @> , рдЬреЛ рдпрд╣ рдЬрд╛рдВрдЪрддрд╛ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рджрд┐рдП рдЧрдП JSONB рдореЗрдВ рдПрдХ рддрддреНрд╡ рдпрд╛ рд╕рд░рдгреА рд╢рд╛рдорд┐рд▓ рд╣реИ:

SELECT '[1, 2, 3]'::jsonb @> '[1, 3]'::jsonb; 

TRUE рджреЗрддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рджрд╛рдИрдВ рдУрд░ рд╕реНрдерд┐рдд рд╕рд░рдгреА рдмрд╛рдИрдВ рдУрд░ рд╕реНрдерд┐рдд рд╕рд░рдгреА рдореЗрдВ рдкреНрд░рд╡реЗрд╢ рдХрд░рддреА рд╣реИред рд▓реЗрдХрд┐рди

 SELECT '[1, 2, [1, 3]]'::jsonb @> '[1, 3]'::jsonb; 

FALSE рджреЗрдЧрд╛, рдХреНрдпреЛрдВрдХрд┐ рдШреЛрдВрд╕рд▓реЗ рдХреЗ рд╢рд┐рдХрд╛рд░ рдХрд╛ рд╕реНрддрд░ рдЕрд▓рдЧ рд╣реИ, рдЗрд╕реЗ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рд╕реЗрдЯ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рдХреНрдпрд╛ рдЕрд╕реНрддрд┐рддреНрд╡ рдСрдкрд░реЗрдЯрд░ рдХреЛ рдЯрд╛рдЗрдкрд╕рди рдХреЗ рд▓рд┐рдП рдкреЗрд╢ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ ? (рдПрдХ рдкреНрд░рд╢реНрди рдЪрд┐рд╣реНрди) рдЬреЛ рдпрд╣ рдЬрд╛рдВрдЪрддрд╛ рд╣реИ рдХрд┐ рдХреНрдпрд╛ JSONB рдореВрд▓реНрдпреЛрдВ рдХреЗ рд╢реАрд░реНрд╖ рд╕реНрддрд░ рдкрд░ рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдПрдХ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреБрдВрдЬреА рдпрд╛ рдХрд┐рд╕реА рд╕рд░рдгреА рдХрд╛ рдПрдХ рддрддреНрд╡ рд╣реИ, рд╕рд╛рде рд╣реА рджреЛ рдФрд░ рд╕рдорд╛рди рдСрдкрд░реЗрдЯрд░ ( рдпрд╣рд╛рдВ рд╡рд┐рд╡рд░рдг)ред рд╡реЗ GIN рдСрдкрд░реЗрдЯрд░реЛрдВ рдХреЗ рджреЛ рд╡рд░реНрдЧреЛрдВ рдХреЗ рд╕рд╛рде GIN рдЕрдиреБрдХреНрд░рдорд┐рдд рджреНрд╡рд╛рд░рд╛ рд╕рдорд░реНрдерд┐рдд рд╣реИрдВред рдСрдкрд░реЗрдЯрд░ -> (рддреАрд░) рдЖрдкрдХреЛ JSONB рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ "рдиреЗрд╡рд┐рдЧреЗрдЯ" рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рдпрд╣ рдХреБрдВрдЬреА рджреНрд╡рд╛рд░рд╛ рдпрд╛ рдЕрдЧрд░ рдпрд╣ рдПрдХ рд╕рд░рдгреА рд╣реИ, рддреЛ рд╕реВрдЪрдХрд╛рдВрдХ рджреНрд╡рд╛рд░рд╛ рдПрдХ рдорд╛рди рд▓реМрдЯрд╛рддрд╛ рд╣реИред рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрдИ рдФрд░ рдСрдкрд░реЗрдЯрд░ рд╣реИрдВред рд▓реЗрдХрд┐рди рдлрд╝рд┐рд▓реНрдЯрд░ рдХреЛ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рдХрд░рдиреЗ рдХрд╛ рдХреЛрдИ рддрд░реАрдХрд╛ рдирд╣реАрдВ рд╣реИ рдЬреЛ WHERE рдХреА рддрд░рд╣ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред рдпрд╣ рдПрдХ рд╕рдлрд▓рддрд╛ рдереА: jsonb рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж, Postgres RDSQL рдХреЗ рд░реВрдк рдореЗрдВ NoSQL рд╕реБрд╡рд┐рдзрд╛рдУрдВ рдХреЗ рд╕рд╛рде рд▓реЛрдХрдкреНрд░рд┐рдпрддрд╛ рдореЗрдВ рдмрдврд╝рдиреЗ рд▓рдЧреЗред

2014 рдореЗрдВ, рдПред рдХреЛрд░реЛрдЯрдХреЛрд╡, рдУред рдмрд╛рд░реНрдЯреБрдиреЛрд╡ рдФрд░ рдПрдлред рд╕рд┐рдЧреЗрд╡ рдиреЗ jsquery рдПрдХреНрд╕рдЯреЗрдВрд╢рди рд╡рд┐рдХрд╕рд┐рдд рдХрд┐рдпрд╛, рдЬрд┐рд╕реЗ рдкреЛрд╕реНрдЯрдЧреНрд░реЗрдЬ рдкреНрд░реЛ рд╕реНрдЯреИрдВрдбрд░реНрдб 9.5 (рдФрд░ рд╕реНрдЯреИрдВрдбрд░реНрдб рдФрд░ рдПрдВрдЯрд░рдкреНрд░рд╛рдЗрдЬ рдХреЗ рдмрд╛рдж рдХреЗ рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдореЗрдВ) рдХреЗ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк рд╢рд╛рдорд┐рд▓ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред рдпрд╣ json (b) рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрддрд┐рд░рд┐рдХреНрдд, рдмрд╣реБрдд рд╡реНрдпрд╛рдкрдХ рд╕реБрд╡рд┐рдзрд╛рдПрдБ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред рдпрд╣ рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдЗрди рдкреНрд░рд╢реНрдиреЛрдВ рдХреЛ рдЧрддрд┐ рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП json (b) рдФрд░ рдЗрдВрдбреЗрдХреНрд╕ рд╕реЗ рдбреЗрдЯрд╛ рдирд┐рдХрд╛рд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдХреНрд╡реЗрд░реА рднрд╛рд╖рд╛ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддрд╛ рд╣реИред рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рджреНрд╡рд╛рд░рд╛ рдЗрд╕ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдереА, рд╡реЗ рд╡реЗрдирд┐рд▓рд╛ рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ рдорд╛рдирдХ рдФрд░ рдирдИ рд╕реБрд╡рд┐рдзрд╛рдУрдВ рдХреЛ рд╢рд╛рдорд┐рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрдВрддрдЬрд╛рд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рдирд╣реАрдВ рдереЗред рд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ рдореВрд▓реНрдп рдЗрд╕ рддрдереНрдп рд╕реЗ рднреА рд╕реНрдкрд╖реНрдЯ рд╣реИ рдХрд┐ рд╡рд┐рдХрд╛рд╕ Wargaming.net рджреНрд╡рд╛рд░рд╛ рдкреНрд░рд╛рдпреЛрдЬрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред рд╡рд┐рд╕реНрддрд╛рд░ рдПрдХ рд╡рд┐рд╢реЗрд╖ рдкреНрд░рдХрд╛рд░ - jsquery рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИред

рдЗрд╕ рднрд╛рд╖рд╛ рдореЗрдВ рдПрдХ рдкреНрд░рд╢реНрди рдХреЙрдореНрдкреИрдХреНрдЯ рд╣реИ рдФрд░ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:

 SELECT '{"apt":[{"no": 1, "rooms":2}, {"no": 2, "rooms":3}, {"no": 3, "rooms":2}]}'::jsonb @@ 'apt.#.rooms=3'::jsquery; 

рд╣рдо рдпрд╣рд╛рдВ рдкреВрдЫ рд░рд╣реЗ рд╣реИрдВ рдХрд┐ рдХреНрдпрд╛ рдЕрдкрд╛рд░реНрдЯрдореЗрдВрдЯ рдмрд┐рд▓реНрдбрд┐рдВрдЧ рдореЗрдВ "рддреАрди рд░реВрдмрд▓" рд╣реИрдВред Jsquery рдкреНрд░рдХрд╛рд░ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП рдХреНрдпреЛрдВрдХрд┐ @@ рдСрдкрд░реЗрдЯрд░ рдЕрдм jsonb рдкреНрд░рдХрд╛рд░ рдореЗрдВ рднреА рд╣реИред рд╡рд░реНрдгрди рдпрд╣рд╛рдБ рд╣реИ , рдФрд░ рдХрдИ рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХреЗ рд╕рд╛рде рдкреНрд░рд╕реНрддреБрддрд┐ рдпрд╣рд╛рдБ рд╣реИ ред

рдХреБрд▓: Postgres рдореЗрдВ JSON рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд╕рдм рдХреБрдЫ рдерд╛, рдФрд░ рдлрд┐рд░ SQL: 2016 рдорд╛рдирдХ рджрд┐рдЦрд╛рдИ рджрд┐рдпрд╛ред рдпрд╣ рдкрддрд╛ рдЪрд▓рд╛ рдХрд┐ рдЗрд╕рдХреЗ рд╢рдмреНрджрд╛рд░реНрде рд╣рдорд╛рд░реЗ jsquery рдХреЗ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рдЕрд▓рдЧ рдирд╣реАрдВ рд╣реИрдВред рдпрд╣ рд╕рдВрднрд╡ рд╣реИ рдХрд┐ рдорд╛рдирдХ рдХреЗ рд▓реЗрдЦрдХреЛрдВ рдиреЗ рднреА jsquery рдкрд░ рдирдЬрд╝рд░ рдбрд╛рд▓реА, JSONPath рдХрд╛ рдЖрд╡рд┐рд╖реНрдХрд╛рд░ рдХрд┐рдпрд╛ред рд╣рдорд╛рд░реА рдЯреАрдо рдХреЛ рдереЛрдбрд╝рд╛ рдЕрд▓рдЧ рддрд░реАрдХреЗ рд╕реЗ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдерд╛ рдЬреЛ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдкрд╣рд▓реЗ рд╕реЗ рдерд╛ рдФрд░ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ, рдмрд╣реБрдд рд╕рд╛рд░реА рдирдИ рдЪреАрдЬреЗрдВ рднреАред

рдПрдХ рд╡рд░реНрд╖ рд╕реЗ рднреА рдЕрдзрд┐рдХ рд╕рдордп рдкрд╣рд▓реЗ, рдорд╛рд░реНрдЪ рдореЗрдВ, рд╣рдорд╛рд░реЗ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдкреНрд░рдпрд╛рд╕реЛрдВ рдХрд╛ рдлрд▓ рдПрд╕рдХреНрдпреВрдПрд▓ рдХреЗ рд▓рд┐рдП рд╕рдорд░реНрдерди рдХреЗ рд╕рд╛рде 3 рдмрдбрд╝реЗ рдкреИрдЪ рдХреЗ рд░реВрдк рдореЗрдВ рд╕рдореБрджрд╛рдп рдХреЛ рдкреЗрд╢ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ : 2016 рдорд╛рдирдХ:

SQL / JSON: JSONPath;
SQL / JSON: рдлрд╝рдВрдХреНрд╢рди;
SQL / JSON: JSON_TABLEред

рд▓реЗрдХрд┐рди рдПрдХ рдкреИрдЪ рд╡рд┐рдХрд╕рд┐рдд рдХрд░рдирд╛ рд╕рдВрдкреВрд░реНрдг рд╡реНрдпрд╡рд╕рд╛рдп рдирд╣реАрдВ рд╣реИ, рдЙрдиреНрд╣реЗрдВ рдмрдврд╝рд╛рд╡рд╛ рджреЗрдирд╛ рднреА рдЖрд╕рд╛рди рдирд╣реАрдВ рд╣реИ, рдЦрд╛рд╕рдХрд░ рдпрджрд┐ рдкреИрдЪ рдмрдбрд╝реЗ рд╣реИрдВ рдФрд░ рдХрдИ рдореЙрдбреНрдпреВрд▓реЛрдВ рдХреЛ рдкреНрд░рднрд╛рд╡рд┐рдд рдХрд░рддреЗ рд╣реИрдВред рд╕рдВрд╢реЛрдзрди рд╕рдВрд╢реЛрдзрди рдХреЗ рдХрдИ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐рдпреЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рдкреИрдЪ рдХреЛ рдмрдврд╝рд╛рд╡рд╛ рджрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП, рдЬреИрд╕рд╛ рдХрд┐ рд╡рд╛рдгрд┐рдЬреНрдпрд┐рдХ рдХрдВрдкрдирд┐рдпрд╛рдВ рдХрд░рддреА рд╣реИрдВ, рдмрд╣реБрдд рд╕рд╛рд░реЗ рд╕рдВрд╕рд╛рдзрдиреЛрдВ (рдорд╛рдирд╡-рдШрдВрдЯреЗ) рдХрд╛ рдирд┐рд╡реЗрд╢ рдХрд░рддреА рд╣реИрдВред рдкреЛрд╕реНрдЯрдЧреНрд░реЗрдЬ рдкреНрд░реЛрдлреЗрд╢рдирд▓, рдЕрд▓реЗрдХреНрдЬреЗрдВрдбрд░ рдХреЛрд░реЛрдЯрдХреЛрд╡ рдХреЗ рдореБрдЦреНрдп рд╡рд╛рд╕реНрддреБрдХрд╛рд░, рдиреЗ рдЗрд╕реЗ рдЦреБрдж рдкрд░ рд▓реЗ рд▓рд┐рдпрд╛ (рдХреНрдпреЛрдВрдХрд┐ рдЕрдм рдЙрдиреНрд╣реЗрдВ рдХрдорд┐рдЯреЗрдЯрд░ рдХрд╛ рджрд░реНрдЬрд╛ рдорд┐рд▓рд╛ рд╣реИ) рдФрд░ рдкреИрдЪ рдХреА рдЗрд╕ рд╢реНрд░реГрдВрдЦрд▓рд╛ рдореЗрдВ рдореБрдЦреНрдп JSONPath рдкреИрдЪ рдХреЛ рдЕрдкрдирд╛рдирд╛ рд╕реБрд░рдХреНрд╖рд┐рдд рд╣реИред рджреВрд╕рд░рд╛ рдФрд░ рддреАрд╕рд░рд╛ рдЕрдм рдиреАрдбреНрд╕ рд░рд┐рд╡реНрдпреВ рдХреА рд╕реНрдерд┐рддрд┐ рдореЗрдВ рд╣реИрдВред рдХреЗрдВрджреНрд░рд┐рдд JSONPath рдЖрдкрдХреЛ JSON (B) рд╕рдВрд░рдЪрдирд╛ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ рдФрд░ рдЗрд╕рдХреЗ рдЯреБрдХрдбрд╝реЛрдВ рдХреЛ рдЙрдЬрд╛рдЧрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рд▓рдЪреАрд▓рд╛ рд╣реИред рдорд╛рдирдХ рдореЗрдВ рдирд┐рд░реНрдзрд╛рд░рд┐рдд 15 рдмрд┐рдВрджреБрдУрдВ рдореЗрдВ рд╕реЗ 14 рдХреЛ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдФрд░ рдпрд╣ рдУрд░реЗрдХрд▓, MySQL рдФрд░ MS SQL рдореЗрдВ рдЕрдзрд┐рдХ рд╣реИред

JSONPath рд╕рдВрдХреЗрддрди JSON рдФрд░ JSQuery рд╕рдВрдХреЗрддрди рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкреЛрд╕реНрдЯрдЧреНрд░реИрдЬ рд╕реНрдЯреЗрдЯрдореЗрдВрдЯ рд╕реЗ рдЕрд▓рдЧ рд╣реИред рдкрджрд╛рдиреБрдХреНрд░рдо рдХреЛ рдмрд┐рдВрджреБрдУрдВ рджреНрд╡рд╛рд░рд╛ рджрд░реНрд╢рд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ:

$ .abc (11 рд╕рдВрдХреЗрддрди рдХреЗ рдмрд╛рдж, рдореБрдЭреЗ 'a' -> 'b' -> 'c') рд▓рд┐рдЦрдирд╛ рд╣реЛрдЧрд╛;
$ - рддрддреНрд╡ рдХрд╛ рд╡рд░реНрддрдорд╛рди рд╕рдВрджрд░реНрдн - рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, $ рдХреЗ рд╕рд╛рде рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ json (рдмреА) рдХреНрд╖реЗрддреНрд░ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддрд╛ рд╣реИ рдЬрд┐рд╕реЗ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рдлрд╝рд┐рд▓реНрдЯрд░ рдореЗрдВ рдПрдХ рднреА рд╢рд╛рдорд┐рд▓ рд╣реИ, рдмрд╛рдХреА рдпрд╣ рдХрд╛рдо рдХреЗ рд▓рд┐рдП рдЙрдкрд▓рдмреНрдз рдирд╣реАрдВ рд╣реИ;
@ - рдлрд╝рд┐рд▓реНрдЯрд░ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдореЗрдВ рд╡рд░реНрддрдорд╛рди рд╕рдВрджрд░реНрдн - $ рдХреЗ рд╕рд╛рде рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдореЗрдВ рдЙрдкрд▓рдмреНрдз рдкрдереЛрдВ рдкрд░ рдкреБрдирд░рд╛рд╡реГрддреНрдд рдХрд░рддрд╛ рд╣реИ;
[*] - рдПрдХ рд╕рд░рдгреА;
* - рд╡рд╛рдЗрд▓реНрдбрдХрд╛рд░реНрдб, $ рдпрд╛ @ рдХреЗ рд╕рд╛рде рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдореЗрдВ рдкрде рдЦрдВрдб рдХреЗ рдХрд┐рд╕реА рднреА рдореВрд▓реНрдп рдХрд╛ рдорддрд▓рдм рд╣реИ, рд▓реЗрдХрд┐рди рдкрджрд╛рдиреБрдХреНрд░рдо рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрддреЗ рд╣реБрдП;
** - $ рдпрд╛ @ рдХреЗ рд╕рд╛рде рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХреЗ рд╣рд┐рд╕реНрд╕реЗ рдХрд╛ рдорддрд▓рдм рдкрджрд╛рдиреБрдХреНрд░рдо рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦреЗ рдмрд┐рдирд╛ рдкрде рдЦрдВрдб рдХреЗ рдХрд┐рд╕реА рднреА рдореВрд▓реНрдп рд╕реЗ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ - рдпрджрд┐ рдЖрдк рддрддреНрд╡реЛрдВ рдХреЗ рдШреЛрдВрд╕рд▓реЗ рдХреЗ рд╢рд┐рдХрд╛рд░ рдХреЗ рд╕реНрддрд░ рдХреЛ рдирд╣реАрдВ рдЬрд╛рдирддреЗ рд╣реИрдВ, рддреЛ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реИ;
рдСрдкрд░реЗрдЯрд░ "?" рдЖрдкрдХреЛ WHERE рдХреЗ рд╕рдорд╛рди рдПрдХ рдлрд╝рд┐рд▓реНрдЯрд░ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ:
$ .abc? (@ .x> 10);
$ .abcxtype (), рд╕рд╛рде рд╣реА рдЖрдХрд╛рд░ (), рдбрдмрд▓ (), рдЫрдд (), рдлрд░реНрд╢ (), abs (), рдбреЗрдЯрд╛рдЯрд╛рдЗрдо (), рдХреАрд╡рд▓реНрдпреВ () рд╡рд┐рдзрд┐рдпрд╛рдВ рд╣реИрдВред
Jsonb_path_query рдлрд╝рдВрдХреНрд╢рди (рдиреАрдЪреЗ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ) рдХреЗ рд╕рд╛рде рдПрдХ рдХреНрд╡реЗрд░реА рдЗрд╕ рддрд░рд╣ рджрд┐рдЦ рд╕рдХрддреА рд╣реИ:

 SELECT jsonb_path_query_array('[1,2,3,4,5]', '$[*] ? (@ > 3)'); jsonb_path_query_array ------------------------ [4, 5] (1 row) 

рд╣рд╛рд▓рд╛рдВрдХрд┐ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд╕рд╛рде рдПрдХ рд╡рд┐рд╢реЗрд╖ рдкреИрдЪ рд╢реБрд░реВ рдирд╣реАрдВ рд╣реБрдЖ рд╣реИ, JSONPath рдкреИрдЪ рдореЗрдВ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА JSON (B) рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд░рдореБрдЦ рдХрд╛рд░реНрдп рд╣реИрдВ:


 jsonb_path_exists('{"a": 1}', '$.a')  true (  "?") jsonb_path_exists('{"a": 1}', '$.b')  false jsonb_path_match('{"a": 1}', '$.a == 1')  true (  "@>") jsonb_path_match('{"a": 1}', '$.a >= 2')  false jsonb_path_query('{"a": [1,2,3,4,5]}', '$.a[*] ? (@ > 2)')  3, 4, 5 jsonb_path_query('{"a": [1,2,3,4,5]}', '$.a[*] ? (@ > 5)')  0  jsonb_path_query_array('{"a": [1,2,3,4,5]}', '$.a[*] ? (@ > 2)')  [3, 4, 5] jsonb_path_query_array('{"a": [1,2,3,4,5]}', '$.a[*] ? (@ > 5)')  [] jsonb_path_query_first('{"a": [1,2,3,4,5]}', '$.a[*] ? (@ > 2)')  3 jsonb_path_query_first('{"a": [1,2,3,4,5]}', '$.a[*] ? (@ > 5)')  NULL 

рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ JSONPath рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐рдпреЛрдВ рдореЗрдВ рд╕рдорд╛рдирддрд╛ рдПрдХрд▓ "=" рд╣реИ, рдЬрдмрдХрд┐ jsquery рдореЗрдВ рдпрд╣ рдбрдмрд▓ рд╣реИ: "=="ред

рдЕрдзрд┐рдХ рд╕реБрд░реБрдЪрд┐рдкреВрд░реНрдг рдЪрд┐рддреНрд░реЛрдВ рдХреЗ рд▓рд┐рдП, рд╣рдо JSONB рдХреЛ рдПрдХрд▓-рд╕реНрддрдВрдн рд╣рд╛рдЙрд╕ рдкреНрд▓реЗрдЯ рдореЗрдВ рдЙрддреНрдкрдиреНрди рдХрд░реЗрдВрдЧреЗ:

 CREATE TABLE house(js jsonb); INSERT INTO house VALUES ('{ "address": { "city":"Moscow", "street": "Ulyanova, 7A" }, "lift": false, "floor": [ { "level": 1, "apt": [ {"no": 1, "area": 40, "rooms": 1}, {"no": 2, "area": 80, "rooms": 3}, {"no": 3, "area": 50, "rooms": 2} ] }, { "level": 2, "apt": [ {"no": 4, "area": 100, "rooms": 3}, {"no": 5, "area": 60, "rooms": 2} ] } ] }'); 


рдЕрдВрдЬреАрд░ред 1 рдЖрд╡рдВрдЯрд┐рдд рдкрддреНрддреА рдЕрдкрд╛рд░реНрдЯрдореЗрдВрдЯ рдХреЗ рд╕рд╛рде рдЖрд╡рд╛рд╕ JSON рдкреЗрдбрд╝ред

рдпрд╣ рдПрдХ рдЕрдЬреАрдм JSON рд╣реИ: рдЗрд╕рдореЗрдВ рдПрдХ рднреНрд░рдорд┐рдд рдкрджрд╛рдиреБрдХреНрд░рдо рд╣реИ, рд▓реЗрдХрд┐рди рдЗрд╕реЗ рдЬреАрд╡рди рд╕реЗ рд▓рд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рдЬреАрд╡рди рдореЗрдВ рдЕрдХреНрд╕рд░ рдпрд╣ рдЖрд╡рд╢реНрдпрдХ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП, рдФрд░ рдХреНрдпрд╛ рдирд╣реАрдВ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рдирдП рд╕рдВрд╕реНрдХрд░рдг рдХреА рдХреНрд╖рдорддрд╛рдУрдВ рдХреЗ рд╕рд╛рде, рд╣рдо рдкрд╣рд▓реА рдФрд░ рджреВрд╕рд░реА рдордВрдЬрд┐рд▓ рдкрд░ рдЕрдкрд╛рд░реНрдЯрдореЗрдВрдЯ рдкрд╛рдПрдВрдЧреЗ, рд▓реЗрдХрд┐рди рдлрд░реНрд╢ рдЕрдкрд╛рд░реНрдЯрдореЗрдВрдЯ рдХреА рд╕реВрдЪреА рдореЗрдВ рдкрд╣рд▓реЗ рдирд╣реАрдВ (рдЬрд┐рд╕ рдкреЗрдбрд╝ рдкрд░ рд╡реЗ рд╣рд░реЗ рд░рдВрдЧ рдореЗрдВ рд╣рд╛рдЗрд▓рд╛рдЗрдЯ рдХрд┐рдП рдЧрдП рд╣реИрдВ):

 SELECT jsonb_path_query_array(js, '$.floor[0, 1].apt[1 to last]') FROM house; --------------------- [{"no": 2, "area": 80, "rooms": 3}, {"no": 3, "area": 50, "rooms": 2}, {"no": 5, "area": 60, "rooms": 2}] 

PostgreSQL 11 рдореЗрдВ, рдЖрдкрдХреЛ рдпрд╣ рдкреВрдЫрдирд╛ рд╣реЛрдЧрд╛:

 SELECT jsonb_agg(apt) FROM ( SELECT apt->generate_series(1, jsonb_array_length(apt) - 1) FROM ( SELECT js->'floor'->unnest(array[0, 1])->'apt' FROM house ) apts(apt) ) apts(apt); 

рдЕрдм рдПрдХ рдмрд╣реБрдд рд╣реА рд╕рд░рд▓ рдкреНрд░рд╢реНрди: рдХреНрдпрд╛ рд╡рд╣рд╛рдБ (рдХрд╣реАрдВ рднреА) "рдорд╛рд╕реНрдХреЛ" рдореВрд▓реНрдп рд╡рд╛рд▓реА рд▓рд╛рдЗрдиреЗрдВ рд╣реИрдВ? рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд╕рд░рд▓:

 SELECT jsonb_path_exists(js, '$.** ? (@ == "Moscow")') FROM house; 

рд╕рдВрд╕реНрдХрд░рдг 11 рдореЗрдВ, рдЖрдкрдХреЛ рдПрдХ рд╡рд┐рд╢рд╛рд▓ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рд▓рд┐рдЦрдиреА рд╣реЛрдЧреА:

 WITH RECURSIVE t(value) AS ( SELECT * FROM house UNION ALL ( SELECT COALESCE(kv.value, e.value) AS value FROM t LEFT JOIN LATERAL jsonb_each ( CASE WHEN jsonb_typeof(t.value) = 'object' THEN t.value ELSE NULL END ) kv ON true LEFT JOIN LATERAL jsonb_array_elements ( CASE WHEN jsonb_typeof(t.value) = 'array' THEN t.value ELSE NULL END ) e ON true WHERE kv.value IS NOT NULL OR e.value IS NOT NULL ) ) SELECT EXISTS (SELECT 1 FROM t WHERE value = '"Moscow"'); 


рдЕрдВрдЬреАрд░ред 2 рд╣рд╛рдЙрд╕рд┐рдВрдЧ JSON, рдорд╛рд╕реНрдХреЛ рдХрд╛ рдкреЗрдбрд╝ рдкрд╛рдпрд╛ рдЧрдпрд╛!

рд╣рдо 40 рд╕реЗ 90 рд╡рд░реНрдЧрдореАрдЯрд░ рдХреЗ рдХреНрд╖реЗрддреНрд░ рдХреЗ рд╕рд╛рде рдХрд┐рд╕реА рднреА рдордВрдЬрд┐рд▓ рдкрд░ рдХрд┐рд╕реА рднреА рдЕрдкрд╛рд░реНрдЯрдореЗрдВрдЯ рдХреА рддрд▓рд╛рд╢ рдХрд░ рд░рд╣реЗ рд╣реИрдВ:

 select jsonb_path_query(js, '$.floor[*].apt[*] ? (@.area > 40 && @.area < 90)') FROM house; jsonb_path_query ----------------------------------- {"no": 2, "area": 80, "rooms": 3} {"no": 3, "area": 50, "rooms": 2} {"no": 5, "area": 60, "rooms": 2} (3 rows) 

рд╣рдо 3 рдХреЗ рдмрд╛рдж рдХреЗ рдХрдорд░реЗ рдХреЗ рд╕рд╛рде рдЕрдкрд╛рд░реНрдЯрдореЗрдВрдЯ рдХреА рддрд▓рд╛рд╢ рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рд╣рдорд╛рд░реЗ рдЖрд╡рд╛рд╕ рдЬреЗрд╕рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░:

 SELECT jsonb_path_query(js, '$.floor.apt.no ? (@>3)') FROM house; jsonb_path_query ------------------ 4 5 (2 rows) 

рдФрд░ рдпрд╣рд╛рдБ рд╣реИ рдХрд┐ рдХреИрд╕реЗ jsonb_path_query_first рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ:

 SELECT jsonb_path_query_first(js, '$.floor.apt.no ? (@>3)') FROM house; jsonb_path_query_first ------------------------ 4 (1 row) 

рд╣рдо рджреЗрдЦрддреЗ рд╣реИрдВ рдХрд┐ рдХреЗрд╡рд▓ рдкрд╣рд▓рд╛ рдорд╛рди рдЪреБрдирд╛ рдЧрдпрд╛ рд╣реИ рдЬреЛ рдлрд╝рд┐рд▓реНрдЯрд░ рд╕реНрдерд┐рддрд┐ рдХреЛ рд╕рдВрддреБрд╖реНрдЯ рдХрд░рддрд╛ рд╣реИред

JSONB @@ рдХреЗ рд▓рд┐рдП рдмреВрд▓рд┐рдпрди JSONPath рдСрдкрд░реЗрдЯрд░ рдХреЛ рдорд┐рд▓рд╛рди рдСрдкрд░реЗрдЯрд░ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрд╣ JSONb_path_match_opr рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХреЙрд▓ рдХрд░рдХреЗ JSONPath рдХреА рдЧрдгрдирд╛ рдХрд░рддрд╛ рд╣реИред

рдПрдХ рдФрд░ рдмреВрд▓рд┐рдпрди рдСрдкрд░реЗрдЯрд░ рд╣реИ @? - рдпрд╣ рдЕрд╕реНрддрд┐рддреНрд╡ рдХреА рдПрдХ рдкрд░реАрдХреНрд╖рд╛ рд╣реИ, рдЗрд╕ рд╕рд╡рд╛рд▓ рдХрд╛ рдЬрд╡рд╛рдм рджреЗрддрд╛ рд╣реИ рдХрд┐ рдХреНрдпрд╛ JSONPath рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ SQL / JSON рдСрдмреНрдЬреЗрдХреНрдЯ рд▓реМрдЯрд╛рдПрдЧрд╛, рдЗрд╕реЗ jsonb_path_exists_opr рдлрд╝рдВрдХреНрд╢рди рдХрд╣рддреЗ рд╣реИрдВ:

  '[1,2,3]' @@ '$[*] == 3'  true;  '[1,2,3]' @? '$[*] @? (@ == 3)' -  true 

рдПрдХ рд╣реА рдкрд░рд┐рдгрд╛рдо рд╡рд┐рднрд┐рдиреНрди рдСрдкрд░реЗрдЯрд░реЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдкреНрд░рд╛рдкреНрдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:

 js @? '$.a'  js @@ 'exists($.a)' js @@ '$.a == 1'  js @? '$ ? ($.a == 1)' 

JSONPath рдмреВрд▓рд┐рдпрди рдСрдкрд░реЗрдЯрд░реЛрдВ рдХреА рд╕реБрдВрджрд░рддрд╛ рдпрд╣ рд╣реИ рдХрд┐ рд╡реЗ GIN рд╕реВрдЪрдХрд╛рдВрдХреЛрдВ рджреНрд╡рд╛рд░рд╛ рддреНрд╡рд░рд┐рдд, рд╕рдорд░реНрдерд┐рдд рд╣реИрдВред jsonb_ops рдФрд░ jsonb_path_ops рд╕рдВрдмрдВрдзрд┐рдд рдСрдкрд░реЗрдЯрд░ рд╡рд░реНрдЧ рд╣реИрдВред рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рд╣рдо SEQSCAN рдХреЛ рдЕрдХреНрд╖рдо рдХрд░ рджреЗрддреЗ рд╣реИрдВ, рдХреНрдпреЛрдВрдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рдорд╛рдЗрдХреНрд░реЛрдПрдмрд┐рд▓рд┐рдЯреА рд╣реИ, рдмрдбрд╝реЗ рдЯреЗрдмрд▓реЛрдВ рдкрд░ рдСрдкреНрдЯрд┐рдорд╛рдЗрдЬрд╝рд░ рдЦреБрдж рдмрд┐рдЯрдореИрдк рдЗрдВрдбреЗрдХреНрд╕ рдХрд╛ рдЪрдпрди рдХрд░реЗрдЧрд╛:

 SET ENABLE_SEQSCAN TO OFF; CREATE INDEX ON house USING gin (js); EXPLAIN (COSTS OFF) SELECT * FROM house WHERE js @? '$.floor[*].apt[*] ? (@.rooms == 3)'; QUERY PLAN -------------------------------------------------------------------------------- Bitmap Heap Scan on house Recheck Cond: (js @? '$."floor"[*]."apt"[*]?(@."rooms" == 3)'::jsonpath) -> Bitmap Index Scan on house_js_idx Index Cond: (js @? '$."floor"[*]."apt"[*]?(@."rooms" == 3)'::jsonpath) (4 rows) 

рдлреЙрд░реНрдо рдХреЗ рд╕рднреА рдХрд╛рд░реНрдп jsonb_path_xxx () рдореЗрдВ рдПрдХ рд╣реА рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рд╣реИрдВ:

 jsonb_path_xxx( js jsonb, jsp jsonpath, vars jsonb DEFAULT '{}', silent boolean DEFAULT false ) 

vars JSONPath рдЪрд░ рдХреЛ рдкрд╛рд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП JSONB рдСрдмреНрдЬреЗрдХреНрдЯ рд╣реИ:

 SELECT jsonb_path_query_array('[1,2,3,4,5]', '$[*] ? (@ > $x)', vars => '{"x": 2}'); jsonb_path_query_array ------------------------ [3, 4, 5] 

рдЬрдм рд╣рдо рдПрдХ рдЯреЗрдмрд▓ рдореЗрдВ рд╕реЗ рдПрдХ рдореЗрдВ рдПрдХ рдЬреЛрдВрд╕рдм рдкреНрд░рдХрд╛рд░ рдХреЗ рдХреНрд╖реЗрддреНрд░ рдХреЛ рд╢рд╛рдорд┐рд▓ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдмрд┐рдирд╛ var рдХреЗ рдХрд░рдирд╛ рдореБрд╢реНрдХрд┐рд▓ рд╣реИред рдорд╛рди рд▓реЗрдВ рдХрд┐ рд╣рдо рдПрдХ рдРрд╕рд╛ рдЖрд╡реЗрджрди рдХрд░рддреЗ рд╣реИрдВ рдЬреЛ рдЙрд╕ рдШрд░ рдХреЗ рдХрд░реНрдордЪрд╛рд░рд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреБрдХреНрдд рдЕрдкрд╛рд░реНрдЯрдореЗрдВрдЯ рдХреА рддрд▓рд╛рд╢ рдХрд░рддрд╛ рд╣реИ рдЬрд┐рдиреНрд╣реЛрдВрдиреЗ рдкреНрд░рд╢реНрдирд╛рд╡рд▓реА рдореЗрдВ рдиреНрдпреВрдирддрдо рдХреНрд╖реЗрддреНрд░ рдХреЗ рд▓рд┐рдП рдЕрдкрдиреА рдЖрд╡рд╢реНрдпрдХрддрд╛рдУрдВ рдХреЛ рд▓рд┐рдЦрд╛ рд╣реИ:

 CREATE TABLE demands(name text, position text, demand int); INSERT INTO demands VALUES ('','', 85), ('',' ', 45); SELECT jsonb_path_query(js, '$.floor[*].apt[*] ? (@.area >= $min)', vars => jsonb_build_object('min', demands.demand)) FROM house, demands WHERE name = ''; -[ RECORD 1 ]----+----------------------------------- jsonb_path_query | {"no": 2, "area": 80, "rooms": 3} -[ RECORD 2 ]----+----------------------------------- jsonb_path_query | {"no": 3, "area": 50, "rooms": 2} -[ RECORD 3 ]----+----------------------------------- jsonb_path_query | {"no": 4, "area": 100, "rooms": 3} -[ RECORD 4 ]----+----------------------------------- jsonb_path_query | {"no": 5, "area": 60, "rooms": 2} 

рд▓рдХреА рдкрд╛рд╢рд╛ 4 рдЕрдкрд╛рд░реНрдЯрдореЗрдВрдЯ рдореЗрдВ рд╕реЗ рдЪреБрди рд╕рдХрддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдпрд╣ рдЕрдиреБрд░реЛрдз рдореЗрдВ 1 рдЕрдХреНрд╖рд░ рдХреЛ рдмрджрд▓рдиреЗ рдХреЗ рд▓рд╛рдпрдХ рд╣реИ - "рдкреА" рд╕реЗ "рд╕реА" рддрдХ, рдФрд░ рдХреЛрдИ рд╡рд┐рдХрд▓реНрдк рдирд╣реАрдВ рд╣реЛрдЧрд╛! рдХреЗрд╡рд▓ 1 рдЕрдкрд╛рд░реНрдЯрдореЗрдВрдЯ рдХрд░реЗрдЧрд╛ред


рдПрдХ рдФрд░ рдЦреЛрдЬрд╢рдмреНрдж рдмрдирд╛ рд╣реБрдЖ рд╣реИ: рдореМрди рдПрдХ рдзреНрд╡рдЬ рд╣реИ рдЬреЛ рддреНрд░реБрдЯрд┐ рд╕реЗ рдирд┐рдкрдЯрдиреЗ рдХреЛ рджрдмрд╛рддрд╛ рд╣реИ, рд╡реЗ рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ рдХреЗ рд╡рд┐рд╡реЗрдХ рдкрд░ рд╣реИрдВред

 SELECT jsonb_path_query('[]', 'strict $.a'); ERROR: SQL/JSON member not found DETAIL: jsonpath member accessor can only be applied to an object 

рддреНрд░реБрдЯрд┐ред рд▓реЗрдХрд┐рди рдпрд╣ рдПрдХ рддреНрд░реБрдЯрд┐ рдирд╣реАрдВ рд╣реЛрдЧреА:

 SELECT jsonb_path_query('[]', 'strict $.a', silent => true); jsonb_path_query ------------------ (0 rows) 

рд╡реИрд╕реЗ, рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ: рдорд╛рдирдХ рдХреЗ рдЕрдиреБрд╕рд╛рд░, рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐рдпреЛрдВ рдореЗрдВ рдЕрдВрдХрдЧрдгрд┐рддреАрдп рддреНрд░реБрдЯрд┐рдпрд╛рдВ рддреНрд░реБрдЯрд┐ рд╕рдВрджреЗрд╢ рдирд╣реАрдВ рджреЗрддреА рд╣реИрдВ, рд╡реЗ рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ рдХреЗ рд╡рд┐рд╡реЗрдХ рдкрд░ рд╣реИрдВ:

 SELECT jsonb_path_query('[1,0,2]', '$[*] ? (1/ @ >= 1)'); jsonb_path_query ------------------ 1 (1 row) 

рдлрд╝рд┐рд▓реНрдЯрд░ рдореЗрдВ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХреА рдЧрдгрдирд╛ рдХрд░рддреЗ рд╕рдордп, рд╕рд░рдгреА рдорд╛рди рдЦреЛрдЬреЗ рдЬрд╛рддреЗ рд╣реИрдВ, рдЬрд┐рдирдХреЗ рдмреАрдЪ 0 рд╣реЛрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди 0 рд╕реЗ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░рдиреЗ рд╕реЗ рдХреЛрдИ рддреНрд░реБрдЯрд┐ рдЙрддреНрдкрдиреНрди рдирд╣реАрдВ рд╣реЛрддреА рд╣реИред

рдЪрдпрдирд┐рдд рдореЛрдб рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдлрд╝рдВрдХреНрд╢рдВрд╕ рдЕрд▓рдЧ рддрд░реАрдХреЗ рд╕реЗ рдХрд╛рдо рдХрд░реЗрдВрдЧреЗ: рд╕рдЦреНрдд рдпрд╛ рд▓рд╛рд▓ (рдЕрдиреБрд╡рд╛рдж рдореЗрдВ "рдЧреИрд░-рд╕рдЦреНрдд" рдпрд╛ "рдвреАрд▓рд╛", рдпрд╣ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рдЪреБрдирд╛ рдЧрдпрд╛ рд╣реИ)ред рдорд╛рди рд▓реАрдЬрд┐рдП рдХрд┐ рд╣рдо JSON рдореЗрдВ рд▓реИрдХ рдореЛрдб рдореЗрдВ рдПрдХ рдХреБрдВрдЬреА рдХреА рддрд▓рд╛рд╢ рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рдЬрд╣рд╛рдВ рдпрд╣ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдирд╣реАрдВ рд╣реИ:

 SELECT jsonb '{"a":1}' @? 'lax $.b ? (@ > 1)'; ?column? ---------- f (1 row) 

рдЕрдм рд╕реНрдЯреНрд░рд┐рдХреНрдЯ рдореЛрдб рдореЗрдВ:

 SELECT jsonb '{"a":1}' @? 'strict $.b ? (@ > 1)'; ?column? ---------- (null) (1 row) 

рдпрд╣реА рд╣реИ, рдЬрд╣рд╛рдВ рдЙрджрд╛рд░ рдореЛрдб рдХреЗ рддрд╣рдд рд╣рдореЗрдВ FALSE рдкреНрд░рд╛рдкреНрдд рд╣реБрдЖ, рд╕рдЦреНрдд рдХреЗ рд╕рд╛рде рд╣рдореЗрдВ NULL рдорд┐рд▓рд╛ред

рд▓реИрдХ рдореЛрдб рдореЗрдВ, рдПрдХ рдЬрдЯрд┐рд▓ рдкрджрд╛рдиреБрдХреНрд░рдо [1,2, [3,4,5]] рдХреЗ рд╕рд╛рде рдПрдХ рд╕рд░рдгреА рд╣рдореЗрд╢рд╛ [1,2,3,4,5] рддрдХ рдлреИрд▓рддреА рд╣реИ:

 SELECT jsonb '[1,2,[3,4,5]]' @? 'lax $[*] ? (@ == 5)'; ?column? ---------- t (1 row) 

рд╕реНрдЯреНрд░рд┐рдХреНрдЯ рдореЛрдб рдореЗрдВ, "5" рдирдВрдмрд░ рдирд╣реАрдВ рдорд┐рд▓реЗрдЧрд╛, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдкрджрд╛рдиреБрдХреНрд░рдо рдХреЗ рдиреАрдЪреЗ рдирд╣реАрдВ рд╣реИред рдЗрд╕реЗ рдЦреЛрдЬрдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ "@" рдХреЛ "@ [*]" рд╕реЗ рдмрджрд▓рдХрд░ рдХреНрд╡реЗрд░реА рдХреЛ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░рдирд╛ рд╣реЛрдЧрд╛:

 SELECT jsonb '[1,2,[3,4,5]]' @? 'strict $[*] ? (@[*] == 5)'; ?column? ---------- t (1 row) 

PostgreSQL 12 рдореЗрдВ, JSONPath рдПрдХ рдбреЗрдЯрд╛ рдкреНрд░рдХрд╛рд░ рд╣реИред рдорд╛рдирдХ рдирдП рдкреНрд░рдХрд╛рд░ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреБрдЫ рдирд╣реАрдВ рдХрд╣рддрд╛ рд╣реИ, рдпрд╣ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреА рд╕рдВрдкрддреНрддрд┐ рд╣реИред рдирдП рдкреНрд░рдХрд╛рд░ рдХреЗ рд╕рд╛рде, рд╣рдореЗрдВ рдЕрдкрдиреЗ рдХрд╛рдо рдХреЛ рддреЗрдЬ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдСрдкрд░реЗрдЯрд░реЛрдВ рдФрд░ рдЕрдиреБрдХреНрд░рдорд┐рддреЛрдВ рдХреА рдорджрдж рд╕реЗ рдЬрд╕рдирд╛рде рдХреЗ рд╕рд╛рде рдкреВрд░реНрдг рдХрд╛рдо рдорд┐рд▓рддрд╛ рд╣реИ, рдЬреЛ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА JSONB рдХреЗ рд▓рд┐рдП рдореМрдЬреВрдж рд╣реИрдВред рдЕрдиреНрдпрдерд╛, JSONPath рдХреЛ рдирд┐рд╖реНрдкрд╛рджрдХ рдФрд░ рдЕрдиреБрдХреВрд▓рдХ рдХреЛрдб рдХреЗ рд╕реНрддрд░ рдкрд░ рдПрдХреАрдХреГрдд рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред

рдЖрдк SQL / JSON рд╕рд┐рдВрдЯреИрдХреНрд╕ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдкрдврд╝ рд╕рдХрддреЗ рд╣реИрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрд╣рд╛рдБ ред

рдУрд▓реЗрдЧ рдмрд╛рд░реНрдЯреБрдиреЛрд╡ рдХрд╛ рдмреНрд▓реЙрдЧ рдкреЛрд╕реНрдЯ SQL / JSON рдорд╛рдирдХ -2016 рдЕрдиреБрд░реВрдкрддрд╛ рдХреЗ рд▓рд┐рдП PostgreSQL, Oracle, SQL Server рдФрд░ MySQL рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╣реИред

рдпрд╣рд╛рдБ SQL / JSON рдкрд░ рдПрдХ рдкреНрд░рд╕реНрддреБрддрд┐ рд╣реИ ред

рдФрд░ рдпрд╣рд╛рдБ SQL / JSON рдХрд╛ рдкрд░рд┐рдЪрдп рд╣реИред

Source: https://habr.com/ru/post/hi448612/


All Articles