Простой список
Если ваш JSON представляет «простой» список комментариев, вам нужно что-то вроде:
select key, value
from datatable, json_each( datatable.data, '$.ALL' )
where json_extract( value, '$.pod' ) = 'fb' ;
, которое, используя ваши образцы данных, возвращает:
2|{"comments":"you like everything","data":["facebook"],"pod":"fb"}
Использование json_each()
возвращает строку для каждого элемента входного JSON (datatable.data
), начиная с пути $.ALL
(где $
- это верхний уровень, а ALL
- этоимя вашего массива: путь может быть опущен, если требуется верхний уровень объекта JSON). В вашем случае это возвращает одну строку для каждой записи комментария.
Поля этой строки задокументированы в 4.13. Табличные функции json_each () и json_tree () в документации по SQLite: нас интересуют: key
(очень приблизительно, "номер строки") и value
(JSON длятекущий элемент). Последний будет содержать элементы с именами comment
и pod
и т. Д.
Поскольку нас интересуют только элементы, в которых pod
равен fb
, мы добавляем предложение where
, используяjson_extract()
для получения в pod
(где $.pod
относительно value
, возвращенного функцией json_each
).
Вложенный список
Если ваш JSON содержит вложенные элементы (то, что я сначала не заметил), затем вам нужно использовать функцию json_tree()
вместо json_each()
. В то время как последний будет перебирать только непосредственные дочерние элементы указанного узла, json_tree()
будет рекурсивно спускаться через всех дочерних узлов из указанного узла.
Чтобы дать нам некоторые данные для работы,Я дополнил ваши тестовые данные дополнительным элементом:
create table datatable ( path string , data json1 );
insert into datatable values("1" , json('
{
"ALL": [{
"comments": "your site is awesome",
"pod": "passcode",
"originalDirectory": "case1"
},
{
"comments": "your channel is good",
"data": ["youTube"],
"pod": "library"
},
{
"comments": "you like everything",
"data": ["facebook"],
"pod": "fb"
},
{
"data": ["twitter"],
"pod": "tw",
"ALL": [{
"data": [{
"codeLevel": "3"
}],
"pod": "mo",
"pod2": "p"
},
{
"comments": "inserted by TripeHound",
"data": ["facebook"],
"pod": "fb"
}]
}
]
}
'));
Если бы мы просто переключились на использование json_each()
, то мы видим, что простой запрос (без предложения where
) вернет все элементы исходного JSON:
select key, value
from datatable, json_tree( datatable.data, '$.ALL' ) limit 10 ;
ALL|[{"comments":"your site is awesome","pod":"passcode","originalDirectory":"case1"},{"comments":"your channel is good","data":["youTube"],"pod":"library"},{"comments":"you like everything","data":["facebook"],"pod":"fb"},{"data":["twitter"],"pod":"tw","ALL":[{"data":[{"codeLevel":"3"}],"pod":"mo","pod2":"p"},{"comments":"inserted by TripeHound","data":["facebook"],"pod":"fb"}]}]
0|{"comments":"your site is awesome","pod":"passcode","originalDirectory":"case1"}
comments|your site is awesome
pod|passcode
originalDirectory|case1
1|{"comments":"your channel is good","data":["youTube"],"pod":"library"}
comments|your channel is good
data|["youTube"]
0|youTube
pod|library
Поскольку объекты JSON смешаны с простыми значениями, мы больше не можем просто добавлять where json_extract( value, '$.pod' ) = 'fb'
, поскольку это приводит к ошибкам, когда value
непредставлять объект. Самый простой способ обойти это - посмотреть значения type
, возвращаемые json_each()
/ json_tree()
: это будет строка object
, если строка представляет объект JSON (другие значения см. В документации выше).
Добавляя это к предложению where
(и полагаясь на «оценку короткого замыкания», чтобы предотвратить вызов json_extract()
для необъектных строк), мы получаем:
select key, value
from datatable, json_tree( datatable.data, '$.ALL' )
where type = 'object'
and json_extract( value, '$.pod' ) = 'fb' ;
, который возвращает:
2|{"comments":"you like everything","data":["facebook"],"pod":"fb"}
1|{"comments":"inserted by TripeHound","data":["facebook"],"pod":"fb"}
При желании мы можем использовать json_extract()
для разбиения возвращаемых объектов:
.mode column
.headers on
.width 30 15 5
select json_extract( value, '$.comments' ) as Comments,
json_extract( value, '$.data' ) as Data,
json_extract( value, '$.pod' ) as POD
from datatable, json_tree( datatable.data, '$.ALL' )
where type = 'object'
and json_extract( value, '$.pod' ) = 'fb' ;
Comments Data POD
------------------------------ --------------- -----
you like everything ["facebook"] fb
inserted by TripeHound ["facebook"] fb
Примечание : если ваша структура содержит другие объекты,Для разных форматов может быть недостаточно просто выбрать type = 'object'
: возможно, вам придется разработать более тонкий процесс фильтрации.