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

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

С Jolt не работал и честно говоря не понимаю, как здесь соблюдается требование, чтобы поле "описание" вытягивалось именно из "последнего" (я так предполагаю, здесь как и в jq порядок ключей сохраняется) блока?

[{
	"operation": "shift",
	"spec": {
		"*": {
			"описание": "isDescript.description",
			"@": "isDescript.details.&"
		}
	}
}]

А, увидел примечание в статье

Будем рассчитывать, что поле "описание" должно присутствовать в искомом блоке. Понятие "последний блок" для JSON несколько не специфично, поскольку стандарт не декларирует порядок "блоков". Иначе, всё сильно усложняется и задача может не иметь решения средствами Jolt Transform.

В таком случае, что будет если поле "описание" будет присутствовать в нескольких "блоках"?

Эта ситуация маловероятна со слов автора вопроса. Но, если взять эту-же спецификацию и пример

{
  "Предупреждения" : {
    "ПРЕДУПРЕЖДЕНИЕ" : "Этот картриджей."
  },
  "Основные характеристики" : {
    "Назначение" : "Для печатающих устройств",
    "Производитель" : "Static Control",
    "Цвет чернил" : "Пурпурный (Magenta)",
    "Тип оборудования" : "Картридж",
    "описание" : "Великолепный картридж",
    "Модель" : "002-01-VF353A"
  },
  "Другие характеристики" : {
    "описание" : "плохой картридж",
    "годен до" : "002-01-VF353A"
  }
}

Получится:

{
	"isDescript": {
		"details": {
			"Предупреждения": {
				"ПРЕДУПРЕЖДЕНИЕ": "Этот картриджей."
			},
			"Основные характеристики": {
				"Назначение": "Для печатающих устройств",
				"Производитель": "Static Control",
				"Цвет чернил": "Пурпурный (Magenta)",
				"Тип оборудования": "Картридж",
				"описание": "Великолепный картридж",
				"Модель": "002-01-VF353A"
			},
			"Другие характеристики": {
				"описание": "плохой картридж",
				"годен до": "002-01-VF353A"
			}
		},
		"description": ["Великолепный картридж", "плохой картридж"]
	}
}

Тип description сменился на массив, а это может быть не очень хорошо для принимающей стороны. Если вы уверены, что такие данные будут вам попадаться, то можно description принудительно сделать массивом.

[{
	"operation": "shift",
	"spec": {
		"*": {
			"описание": "isDescript.description[]",
			"@": "isDescript.details.&"
		}
	}
}]

Так и думал, спасибо

NiFi под рукой нет, но нашел песочницу, в которой можно прогнать и получить этот результат: https://jolt-demo.appspot.com

Вообще, тема довольно интересная, но получается специфика NiFi не раскрыта, больше про Jolt.

С NiFi я тоже не работал, поэтому для меня было бы полезно увидеть производительность таких трансформаций, может еще какие-то подводные камни или лайфхаки. Например, можно ли следующим шагом поставить валидитор JSON по схеме, чтобы как раз такие "незапланированные" документы отправились не в основной поток, а в соседний для разбора таких ситуаций.

Да, можно.... Например, будет такая цепочка процессоров.

В RouteOnAttribute проверять размерность массива

Именно из "последнего" - никак... об этом есть в ремарка в тексте.

По итогам обсуждения задачи стало понятно, что искать "последнее" не требуется. Там посыл был такой - ожидается, что поле "описание" будет в каждом файле и именно в последнем блоке, даже если там блок один.

Т.е. будет один блок с полем "описание". А вот в названии ключа этого блока, который тут - "основные характеристики" могло быть всё, что угодно.

Если было бы несколько "описаний" и брать именно из последнего, то задача сильно усложнится...

В уже упомянутом телеграмм-канале подсказали, что я заблуждаюсь насчет последнего элемента. И если подумать, то вырисовывается такое решение:

[{
	"operation": "shift",
	"spec": {
		"@": ["isDescript.details", "arr"]
	}
}, {
	"operation": "shift",
	"spec": {
		"arr": {
			"*": "arr[]"
		},
		"*": "&"
	}
}, {
	"operation": "modify-overwrite-beta",
	"spec": {
		"arr": "=lastElement(@(1,arr))"
	}
}, {
	"operation": "shift",
	"spec": {
		"arr": {
			"описание": "isDescript.description"
		},
		"*": "&"
	}
}]

которое даёт

{
	"isDescript": {
		"details": {
			"Предупреждения": {
				"ПРЕДУПРЕЖДЕНИЕ": "Этот картриджей."
			},
			"Основные характеристики": {
				"Назначение": "Для печатающих устройств",
				"Производитель": "Static Control",
				"Цвет чернил": "Пурпурный (Magenta)",
				"Тип оборудования": "Картридж",
				"описание": "Великолепный картридж",
				"Модель": "002-01-VF353A"
			},
			"Другие характеристики": {
				"описание": "Плохой картридж",
				"Модель": "002-01-VF353A"
			}
		},
		"description": "Плохой картридж"
	}
}

хотя, лучше даже будет охватить такой вариант, когда последний блок не содержит "описание" и нужно получить последний из тех, что всё-таки содержат:

[{
	"operation": "shift",
	"spec": {
		"@": ["isDescript.details", "arr"]
	}
}, {
	"operation": "shift",
	"spec": {
		"arr": {
			"*": "arr[]"
		},
		"*": "&"
	}
}, {
	"operation": "shift",
	"spec": {
		"arr": {
			"*": {
				"описание": "arr"
			}
		},
		"*": "&"
	}
}, {
	"operation": "modify-overwrite-beta",
	"spec": {
		"arr": "=lastElement(@(1,arr))"
	}
}, {
	"operation": "shift",
	"spec": {
		"arr": "isDescript.description",
		"*": "&"
	}
}]

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории