Как получить подполе карты типа структуры, в поисковом ответе YQL-запроса в Vespa? - PullRequest
0 голосов
/ 02 января 2019

Пример данных:

"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 Ответ

0 голосов
/ 02 января 2019

Пример запроса YQL, я думаю, должен проиллюстрировать, что вы хотите, так как этот синтаксис недопустим.Выбор данного ключа из поля Lang of map типа может быть выполнен так же, как и в вашем поисковике, но десериализация в JSON и анализ JSON, вероятно, неэффективны, так как StructuredData реализует интерфейс Inspectable, и вы можете проверить его напрямую без необходимости проходить через JSON.формат.Смотри https://docs.vespa.ai/documentation/reference/inspecting-structured-data.html

...