Как получить подполе карты типа структуры, в поисковом ответе YQL-запроса в Vespa?
Пример данных:
"fields": {
"key1":0,
"key2":"no",
"Lang": {
"en": {
"firstName": "Vikrant",
"lastName":"Thakur"
},
"ch": {
"firstName": "维克兰特",
"lastName":"塔库尔"
}
}
}
Ожидаемый ответ:
"fields": {
"Lang": {
"en": {
"firstName": "Vikrant",
"lastName":"Thakur"
}
}
}
Я добавил следующее в мое определение поиска demo.sd:
struct lang {
field firstName type string {}
field lastName type string {}
}
field Lang type map <string, lang> {
indexing: summary
struct-field key {
indexing: summary | index | attribute
}
}
Я хочу написать запрос yql что-то вроде этого (это не работает):
http://localhost:8080/search/?yql=select Lang.en from sources demo where key2 contains 'no';
Мой временный обходной подход
Я реализовал пользовательский поисковик в MySearcher.java, с помощью которого я могу извлечь необходимое подполе, установить новое поле defaultLang и удалить поле "Lang". Ответ, сгенерированный поисковиком:
"fields": {
"defaultLang": {
"firstName": "Vikrant",
"lastName":"Thakur"
}
}
Я написал следующее в MySearcher.java:
for (Hit hit: result.hits()) {
String language = "en"; //temporarily hard-coded
StructuredData Lang = (StructuredData) hit.getField("Lang");
Inspector o = Lang.inspect();
for (int j=0;j<o.entryCount();j++){
if (o.entry(j).field("key").asString("").equals(language)){
SlimeAdapter value = (SlimeAdapter) o.entry(j).field("value");
hit.setField("defaultLang",value);
break;
}
}
hit.removeField("Lang");
}
Edit-1: вместо этого более эффективный способ - использовать интерфейс Inspectable и Inspector, как описано выше (спасибо @Jo Kristian Bergum)
Но в приведенном выше коде мне нужно перебрать все языки, чтобы отфильтровать нужный. Я хочу избежать этой сложности времени O(n) и использовать структуру карты для доступа к ней в O(1). (Потому что количество языков может увеличиться до 1000, и это будет сделано для каждого удара.)
Все это связано с типом данных StructuredData, который я получаю в результатах. StructureData не сохраняет структуру карты, а дает массив JSON, например:
[{
"key": "en",
"value": {
"firstName": "Vikrant",
"lastName": "Thakur"
}
}, {
"key": "ch",
"value": {
"firstName": "维克兰特",
"lastName": "塔库尔"
}
}]
Пожалуйста, предложите лучший подход вообще или любую помощь с моим текущим. Оба ценятся.
1 ответ
Пример запроса YQL, я думаю, должен проиллюстрировать, что вы хотите, так как этот синтаксис недопустим. Выбор данного ключа из поля Lang of map типа может быть выполнен так же, как и в вашем поисковике, но десериализация в JSON и анализ JSON, вероятно, неэффективны, поскольку StructuredData реализует интерфейс Inspectable, и вы можете проверить его напрямую без необходимости проходить через JSON. формат. См. https://docs.vespa.ai/documentation/reference/inspecting-structured-data.html