Обзор вариантов вывода результатов в JSON виде

Обзор вариантов вывода результатов в JSON виде

Вопросы о выводе результатов в JSON являются довольно частыми среди всех обращений в Техническую поддержку. Поэтому мы подготовили небольшой обзор всех возможных способов это сделать.
В качестве "подопытного" возьмем парсер Google подсказок SE::Google::Suggest SE::Google::Suggest. Также для большей наглядности условимся что в результате нам необходимы сам запрос, кол-во подсказок по нему, непосредственно сами подсказки и количество символов в каждой подсказке (ее длина).

1. Вывод в JSON для одиночных запросов
Простейший вариант вывода в JSON - это использование метода шаблонизатора .json:
Код:
[% obj = {};
obj.query = query;
obj.count = p1.totalcount;
obj.suggests = [];

FOREACH item IN p1.results;
    obj.suggests.push({
        keyword = item.suggest
        length = item.suggest.length
    });
END;

obj.json %]
Здесь мы в Общем формате результата создаем пустой объект obj, записываем в него две переменные (запрос query и кол-во результатов по нему count) и пустой массив suggests. После чего наполняем массив объектами, содержащими подсказку keyword и кол-во символов в ней length. Тем самым получается нужная структура. И выводим это все в виде JSON строки:
Код:
{"suggests":[{"keyword":"testzentrum","length":11},{"keyword":"teste dich","length":10},{"keyword":"testosterone","length":12},{"keyword":"testzentrum in der nähe","length":23},{"keyword":"testosteron","length":11},{"keyword":"testdaf","length":7},{"keyword":"test center near me","length":19},{"keyword":"testament","length":9}],"count":8,"query":"test"}
Этот способ отлично подходит для одиночных запросов, например через API метод oneRequest.
eJxtVE1v2zAM/SuG0AItEBjrYRcPO6RZsnXI4i5pT04OWky7SmTRk+R0heH/Xkp2
7CTryeLj49cTrZpZbvbmUYMBa1iU1Kz0ZxaxFDJeSctGrOTagHbuhK2mUfQdMZcQ
Rasqz8E4xpG72YwYxdPRzFAX3OVJrgP8swu+BnXzZa3oGP6tQL8R4L8dtsVKWcLK
u9Ci5dLbnc+0dQy5kw1hazWLl9Px5EcgLBTBw8JFdWWd254GhWVlXm5qB6/tHt5e
UaeUyEUeOa1Pgsrty4UrbFHHaG4p93TxzTfgKuwMquB6w/qRV/wAT0gjZ0LCAM/I
WvACyHGVcgvOG2Zenpvb0P5zAvI0FVag4rLVzYk9aPmsBGlF8QqJ62QTYGYaC4Is
+ARey6PmCbvyNqMUlY/93cawKOPSwIgZanXGqZH00kPTa25Rx6Xrh/CaoRpLOYcD
yIHm899XQqa0GeOMgh66wI8p8X85mn6801IH0K+aeuizeOs+/jVEpTjH/CiGFIWw
ZJuJWxhCPxG4Byh7zRaOVqCGvkyXuatOy1+CSok5XNm4HKCzMc6u5RzcospEHtMA
WqRwZFbqif6wWE2wKCW4uVQlJV2LgeWwHmPTXYMzhgYvgye+xNm/aRGl+blqWy21
oPX77BosSMnTql3KLZfyeTk/9bBhpfw6+R96S3uaI20QTdFs+iegfyjqDx+CqG7o
fnbmsWW7YRyXMFLFkPgsumveAdRolQE=

2. Формирование JSON построчно
Но что будет, если в предыдущем случае подать на вход несколько запросов? Проверим, добавив для удобства перевод строки после вывода JSON. И попробуем поработать с полученным JSON'ом, вставив его в любой редактор JSON:
le367_220929155225.png

Как видно на скриншоте, мы получили ошибку, т.к. JSON не валиден. Сейчас это по сути набор строк, который не отвечает правилам JSON.

Самым очевидным решением по формированию валидного JSON'а для нескольких запросов (да и в целом для любого количества больше одного) является использование массива. Если посмотреть на любой массив в JSON, то он похож на строки, разделенные запятыми. И все это взято в квадратные скобки. Что ж, добавим к выводу запятые (вместе с переводом строки, в формате результата) и квадратные скобки в самом начале и конце (воспользуемся для этого функционалом Начального и Конечного текстов).

Код шаблона в Формате результата по сути остается такой же, как и предыдущем примере, только добавляется запятая после каждой строки (и перевод строки для удобства):
Код:
obj.json _ ",\n"
Начальный и Конечный тексты:
scim8_220929160634.png

Получаем такой результат:
p6877_220929161029.png

Как видим, снова ошибка:(
Если изучить то, что получилось - становится понятно, что все портит запятая в самом конце (на скрине выделена стрелкой). Но она выводится вместе со строкой JSON'а и нет возможности указать парсеру что какая-то строка последняя и запятую выводить не нужно...

Вполне неплохим решением в этой ситуации будет добавление пустого объекта в самый конец. Для этого просто пропишем его в Конечном тексте.
mn0kl_220929161508.png

Теперь, если запустить пресет, получим валидный JSON в виде массива объектов, где каждый объект - это данные по каждому запросу.
kmana_220929161801.png

При дальнейшей обработке пустой объект можно просто игнорировать.
eJxtVN9v2jAQ/lciq5VaCUWt2r1k2gNlsHVipIP2CdDkkUtqcOzMdtpVUf733Tkh
AdqXxPfd7893rpjjdmcfDFhwlkXLihX+zCKWQMpL6diAFdxYMKRessU4ir5pnUmI
okWZZWDJYm+7Xg8Y+uPRTrTJOcVZngf6zzb4ElT155XCY/i3BPOGgP+32EaXyiFW
XIdOOy693Opsk8eierlGbKUm8Xw8HH0PhIM8uJ+RV5uW1O7QKSxK+3xREbxyO3h7
1SbBQOS5t2l0ElTmnk9UYYOSRX2Jscezr74AyrC1WgW/gxUbrBBiwfmadd0v+As8
auw+FRJ6eILSjOeAirOEOyBtmHqmLi5D94+45EkinNCKy4ZC4r2n9UkJpA39lUZb
YlCAnRidI+TAB/C07ulfsjMvMwxRet9fjQ+LUi4tDJjFUiccC0lONUiE4U6buKB6
EK+YVkMpp/ACsjfz8e9KIRMckmGKTvet48cm8bsYddfeYaoXMK8Ga+iieOku/tl7
JXqqsz0ZUuTCoWxHNDuIXiG4Ayg6zmZklmsDXRpnSuiS4xoUoBKa2f7KhkWLVfWa
nXRydDPH4EarVGQx9mBEAnvLUj3ivsVqpPNCArWmSinxZizM+wkZ2vYmSOi6f+c8
8imONtVpLe2PBWK0tkbgBH6iAnMk8zBrG3LDpXyaTw81rJ8qP1G0Hc3+44yXV7c3
qf+C/94cnG/9lyjf4GBnGkcOe67X3fPRPTLVh49IVNV4oVv70FhT62SLGHJo8bZY
dF3/B8Dop6s=

2.1. Избавляемся от пустого обьекта
Но как быть, если по какой-то причине пустой объект в конце недопустим? Существует небольшой лайфхак. Надо немного изменить логику построчного формирования и выводить запятую не в конце каждой строки, а в начале. И нужно завести переменную, которая будет играть роль флага, указывающего ставить ли запятую или нет. В примере ниже это переменная notFirst.
Итого шаблон для Формата результата будет выглядеть так:
Код:
[% IF notFirst;
    ",\n";
ELSE;
    notFirst = 1;
END;

obj = {};
obj.query = query;
obj.count = p1.totalcount;
obj.suggests = [];

FOREACH item IN p1.results;
    obj.suggests.push({
        keyword = item.suggest
        length = item.suggest.length
    });
END;

obj.json %]
Не забудьте убрать пустой объект из Конечного текста.
В результате получаем валидный JSON без пустых объектов.
eJxtVN9v2jAQ/lciq5VaCUVF7V5S7YEysjEx6KB9Ah48ckkNjp3ZTrsq4n/fnRMS
oH2xfd/98N13Z1fMcbuzjwYsOMuiZcUKf2YRSyDlpXSsxwpuLBhSL9liFEXftc4k
RNGizDKwZHGwXa97DP3xaGNtck5xlpfBOA6UdrEw1t2v1MqtWG+FO0NhNFmMPHYw
CL4GfcKn3whW+s8WkWp/74/h3xLMOwJ+b7CNLhW5Ff3QacellxudrVO0qF6ufcB4
Nh8Nhj8C4SAPxlPyajL2aRw7hUVpX64qn7HbwfubNgkGIs+DTa2ToDL3cqYKa5Qs
9tenFYVbq1VwuWYtWwv+Ck8a2UqFhA6OUZryHFBxkXAHpA1Tz+zVdej+Efc8SYQT
WnFZU0596trwrARyhf5Koy3RJsDGRucIOfABPJeHdi3ZhZcZhii97+/ah0UplxZ6
zGKqMcdEknMNVm+402ZWUD6IV0yrgZQTeAXZmfn4D6WQCQ7VIEWnceP4ucnsQ4x9
W97xVa9g3gzm0Ebx0sPsV+eV6InODmRIkQuHsh3SwCB6g+AOoGg5m5JZrg201zhT
Qns5PpsCVEIz3rVsUDTYmp3VcdKXU3CjVSqyGVZgRAIHy1I94eucqaHOCwlUmCql
xL5YmHfzMbBNH0hoa//gPPRXnLxrp7W0PxeI0SM3AufvCyWYI5XHtzYhN1zK5/nk
WMO6mfLzRA+i/i1w0subu9vUr+DX26PznV+J8A2OdaZx4LDm/br9bNovqfr0y4mq
PbZzax9rayqdbBFDDi32ikX9/X/SQbem
Данный метод не имеет никаких ограничений по кол-ву запросов и объёму результатов. Его вполне можно использовать для любых задач, требующих вывод в JSON.
Но существует еще один способ и о нем ниже.

3. Формирование объекта в памяти и вывод результатов в JSON в конце работы задания
Выше мы для нескольких запросов выводили данные в массив. Но как быть, если по какой-то причине массив нам не подходит и нужен один большой объект? И чтобы ключами в этом объекте были подаваемые на вход запросы...
Решение есть. Нужно создать в самом начале работы задания пустой объект, писать в него данные по ходу парсинга и в конце работы задания вывести все это в результат. Поможет все это реализовать опять же функционал Начального и Конечного текстов. Как известно, Начальный отрабатывает в самом начале работы задания, а Конечный - в конце. Этим и воспользуемся.

Итак, в Начальном тексте пропишем создание пустого объекта (используя шаблонизатор):
Код:
[% obj = {} %]
В Общем формате результата пропишем запись в этот объект:
Код:
[% obj.${query} = {};
obj.${query}.count = p1.totalcount;
obj.${query}.suggests = [];

FOREACH item IN p1.results;
    obj.${query}.suggests.push({
        keyword = item.suggest
        length = item.suggest.length
    });
END %]
И в Конечном тексте пропишем вывод в JSON:
Код:
[% obj.json %]
Запускаем и получаем JSON в требуемом виде:
l7uyb_220929165640.png

Код:
eJxtVN9v2jAQ/lcii0qtVEWt2r1k2gNlsHVi0EL7BDx45JIaHDuzHboqyv++OwcS
QnmxfHff/fjuzi6Z43ZrnwxYcJZFi5Ll/s4iFkPCC+nYNcu5sWDIvGDzYRT90DqV
EEXzIk3BEuKAXa2uGfrj1Y60yTjFWVwE+s8m7JV/CzAfVfAtKKuvS3WsC9e6UA4t
+W3otOPSy6cgW6eziFus0LhUo+ls2B/8DISDLHickPs+O5ndWe8wL+zbZUn2pdvC
x7s2MUakEAdMbZOgUvd2YgprLSGqK0wynHwPLlasYT3nO3jRyDoRElr1CKUJzwAN
vZg7IGuY+A5dXoXuH/WQx7FwQisu69ZRv9t2viqBRNBfacQSJwF2ZHSGKgc+gCd6
aPuC9bzMMEThfZ9rHxYlXFq4ZhZLHXEsJD61IGHDnTbTnOpBfcm06ks5hh3IFubj
PxRCxrgc/QSdHveO5yHTTzGqht5xqh2Yd4M1NFG89DD93XrFeqzTQzOkyIRD2Q5o
a1B7g8otQN70bEKwTBto0jhTQJMc1z8HFTe76le0M9Z+3gGEG6tVDegw7Eysq1xr
lYh0ityMiOGALNQLvr+pGugsl0CUVSElTszCrN2cvt1PiISmK5+cBz5F5+U6raX9
NUcdPWMjcDO/UIEZNvk46z7kmkv5OhsfW1i7bX7T6HXU/wG+geLm/i7xJ/jz7uh+
708axRoXPtW4isi5WjXfSfPplGc/laiscNAb+1SjiTphUYc9tDhFFt1W/wG6160c
Благодаря хранению данных в памяти, можно дополнительно перед выводом в результат произвести с ними различные действия. К примеру отсортировать или произвести подсчет какой-то статистики. Кроме этого данный метод более удобен для логического понимания его работы, в отличие от вышеописанного построчного вывода, который является несколько нетипичным вариантом формирования JSON. Но у этого варианта есть один существенный минус. Его нельзя использовать для очень больших объёмов запросов, т.к. из-за хранения всех данных в памяти можно попросту упереться в ее нехватку. Также итоговый вывод или пост-обработка собранных результатов на большом количестве запросов может занять много времени и привести к ошибкам в работе А-Парсера.


В этой статье мы рассмотрели все варианты вывода результатов в JSON. Какой использовать - зависит от решаемых задач. Оптимальным является построчный вывод, но если нужно сделать какую-то пост-обработку собранных результатов "на лету" - то лучше использовать 3-й метод.
  • Like
Реакции: Evgeniy.O
Автор
Support
Просмотры
28
Первый выпуск
Обновление

Рейтинги

5,00 звёзд Оценок: 1

Ещё ресурсы от Support

Назад
Верх