Как стать автором
Обновить

Комментарии 28

Обновляем значение объекта по ключу. 25 здесь является числом, но взято в кавычки, потому что присваиваемое значение должно быть jsonb
А если я хочу записать 25 как строку?
В коммите в примере:
update test_jsonb_subscript set test_json['a'] = '1' where id = 1;
select * from test_jsonb_subscript;
 id |    test_json     
----+------------------
  2 | {"key": "value"}
  1 | {"a": 1}
(2 rows)
Пишу строку, записывается как число. Это, как по мне, контринтуитивно.

Ага… т.е. когда надо сделать такое как ниже, то нужно будет и далее кастить?
И если вот это вероятно будет работать и без cast(age as varchar) (из за нативного неявного преобразования между numeric и varchar):


select * from t1 where jf['age'] in (select cast(age as varchar) from t2)

то здесь нужно будет обязательно обернуть в кавычки?


select * from t1 where jf['name'] in (select '"' || name || '"' from t2)

Серьезно?..
Если так, то это несколько сомнительная реализация (как минимум какое-то половинчатое решение)…
Почему нельзя было сделать типизированный implicit cast (implicit conversion)? Ведь если это зарелизят в таком виде, то позже '25' на вход json "навсегда" останется numeric (для структур json), и "нормальный" inplace cast (где это varchar а не numeric) уже нельзя будет сделать позже из-за потери совместимости.

наверно надо будет вот так оборачивать (точно не знаю)
select * from t1 where jf['name'] in (select name::json from t2)

Ну то есть все индексы побоку? fullscan по выражению? :) Тогда уж что-нибудь типа такого:


select * from t1 where jf['name']::varchar in (select name from t2)

Только, чем оно лучше того же ->> тогда? Сформулирую по другому, зачем еще один "странный" сахар для ->> (неее, даже не для ->> а для ->)...


- select '{"name":"John"}'::json->>'name'
- select '{"name":"John"}'::json->'name'::varchar
+ select '{"name":"John"}'::json['name']::varchar
Может быть там nullsafe? Попытка сделать последовательное обращение через указанные вами операторы сдохнет на первой же строке где свойства нет, насколько я помню.

База становится всё лучше и лучше, приятнее и приятнее!!! :) Спасибо!

Не подскажете, а в MariaDB (MySQL) если тип поля JSON, есть какие-то методы чтобы аналогично обращаться и обновлять частично поля в структурах?
Документация говорит, что есть такое. Правда, я работал с JSON только в PG и не знаю, насколько он проработан в MySQL.

mariadb.com/kb/en/json-data-type
mariadb.com/kb/en/json-functions

Приходилось один раз это использовать. В сравнении с PGSQL – поддержка слабая. Лично мне не хватило аналога unnest при работе с mariadb.


Пример mysql-реализации для дочерних элементов любого типа

source.


SELECT
  rec_num,
  idx,
  JSON_EXTRACT(jdoc, CONCAT('$.fish[', idx, ']')) AS fishes
FROM t1
  -- Inline table of sequential values to index into JSON array
JOIN ( 
  SELECT  0 AS idx UNION
  SELECT  1 AS idx UNION
  SELECT  2 AS idx UNION
  -- ... continue as needed to max length of JSON array
  SELECT  3
  ) AS indexes
WHERE JSON_EXTRACT(jdoc, CONCAT('$.fish[', idx, ']')) IS NOT NULL
ORDER BY rec_num, idx;

Обычно, у postgresql с записью json/jsonb проблем нет, новый синтаксис — тоже хорошо. Проблемы начинаются, когда пытаетесь вытащить значения в виде скаляров и их использовать здесь же в запросе. Тогда начинаются пляски с документацией и кастованием.

Или если нужен доступ к элементам массива, или доступ к элементам при условии что родитель есть не во всех строках.
Да я знаю, но если ее использовать то поиск по индексу накрывается медным тазом
Особенно вот такой «сахар»:

json_each(
 CASE
  WHEN (json_typeof(some_json_column) = 'null') THEN NULL
  ELSE some_json_column
 END
)

Можно ли это как-то заиспользовать в Entity Framework?

А какие ограничения мешают сразу сделать нормально и интуитивно: something['foo'] = 42 для числа и something['bar'] = 'baz' для строки?

Это можно было тупо сделать для скалярных элементов, а для того что бы вставить json, можно было просто указать это явно:


-- set int, string and json:
fld['foo'] = 42,  fld['str'] = 'text',  fld['bar'] = '{"a": 1, "b": 2}'::json
согласен
А вот мне интересно. Как выучить язык с нуля? Синтаксис и все такое??
Официальная документация — хороший старт )
Язык-то совсем фигня. Прелести начинаются, когда, казалось бы, запрос, отдающий требуемое, отдаёт это, скажем, за часы. Начинаются длительные ковыряния в планах запросов (как explain, так и explain analyze, второй — вообще пушка, ведь ему надо исполниться, чтобы посчитать тайминги и прочие условия выполнения, то есть, ждём эти самые часы). Потом начинаются всякие ковыряния в особенностях конкретной реализации конкретной версии СУБД. Ну, типа, мускль в запросе предпочитает использовать индекс, а ровно в таком же запросе на тех же данных постгрес упорно сексканит, а то и вообще временные таблицы на диске заводит. В общем, веселье.
Обычно наоборот, для новичка оптимизатор PG — просто рай. Как правило запрос работающий очень долго — признак неправильной архитектуры. Иногда на такое, конечно идешь сознательно если архитектура не устойчива в моменте, но все равно, часы? О_О
Да легче лёгкого. Порядка 20-30 критериев в WHERE и вот уже глаз замыливается и пропускает, что критерий связывания для JOIN мы пропустили. А там миллионы строк.

Помнится, например, были засады с btree совместно с BETWEEN (вроде, пофиксить должны были уже). Ну какой новичок сходу сообразит, чего это оптимизатор на индексном поле вдруг SEQ SCAN влупил?
Да я до сих пор когда between пишу в голове это держу, я потому и перешел на пг с концами потому что достало с бубном вокруг mysql прыгать.
А про join и where даа, поэтому у меня форматор ставил столбцы один над другим в условиях и where на одном уровне с from а left join on с отступом. Хотя все равно несколько раз промахивался при копировании условий когда очень большие блоки с условии и кучей разных операторов.
Читать вообще все что найдете по PostgreSQL и пробовать все.
Возможно Вам покажется уместным использовать вместо слова костыли другое — ходули.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории