Получите выходные данные, отличные от входных, с помощью подсказки завершения elasticsearch

Я недавно обновился с Elasticsearch 1.4 до 5.4, и мне сложно эффективно переносить запросы автозаполнения. Проблема в том, что я хочу иметь подсказчик завершения, где вывод отличается от ввода.

В документах, которые я храню, есть поле для категорий, которое в основном представляет собой массив строк с их URI (потому что они образуют дерево). Последняя часть URI, которую я называю меткой, является вводом в подсказчик завершения, но в качестве ответа я хотел бы получить полный URI.

Допустим, у меня есть два документа:

{
    "name" : "Lord of The Rings",
    "categories" : ["Books/Genre/Fantasy", "Books/Language/English"]
}

и

{
    "name" : "Game of Thrones",
    "categories" : ["Series/Genre/Fantasy", "Series/Host/HBO"]
}

Я ввел «Фант», и я хочу получить в ответ URI для категорий «Сериал / Жанр / Фэнтези» и «Книги / Жанр / Фэнтези».

Ранее с ES 1.4 я мог создать подсказчик завершения с другим выводом для данного ввода, поэтому я проиндексировал своих подсказчиков следующим образом:

{
    "suggest" : {
        "input": [ "Fantasy"],
        "output": "Series/Genre/Fantasy"
    }
}

и

{
    "suggest" : {
        "input": [ "Fantasy"],
        "output": "Books/Genre/Fantasy"
    }
}

Но в ES 5.4 свойство output больше не существует для подсказчиков завершения, поэтому все, что я получаю в ответ, - это свойство input моего поля подсказки, которое является меткой «Fantasy», но мне нужен URI.

Прямо сейчас мой обходной путь - искать поле categories каждого документа, возвращенного в свойстве _source ответа, и фильтровать категории, у которых есть метка, начинающаяся с ввода «Fant». Это очень неэффективно, так как мне нужно сопоставить каждую категорию каждого возвращенного документа с его меткой, чтобы проверить ввод.

Нет более эффективного способа сделать это с помощью суггестеров ES? Что мне не хватает?


person WhiteFangs    schedule 01.08.2017    source источник


Ответы (1)


Подсказка завершения Elasticsearch была изменена с 5.0. Поддержка указания вывода при индексировании записей предложений была удалена. Теперь текст записи результата предложения всегда является непроанализированным значением ввода предложения (то же самое, что и отсутствие указания вывода при индексировании предложений в индексах до версии 5.0). Таким образом, вам нужно добавить output в качестве родственного поля ключа suggest в теле.
Вот как это должно выглядеть:

Сопоставление:

{
    "mappings": {
        "<type>" : {
            "properties" : {
                "suggest" : {
                    "type" : "completion"
                },
                "output" : {
                    "type": "keyword"
                }
            } 
        }
    }
}

Не забудьте заменить <type> на свой тип индекса.

Индексирование:

/<index_name>/<type_name>

{
    "suggest" : {
        "input": ["Fantasy"],
        "weight" : 1
    },
    "output": "Series/Genre/Fantasy"
}

Здесь имя поля output может быть заменено чем угодно, это просто метаданные вашего документа.

Запрос:

/<index_name>/_search

{
    "suggest": {
        "show-suggest" : {
            "prefix" : "Fant",
            "completion" : {
                "field" : "suggest"
            }
        }
    }
}

Надеюсь, это поможет.

person mayankchutani    schedule 12.08.2017
comment
Это не решает мою проблему, потому что в конечном итоге я использую тот же способ обхода, что и сейчас: просматриваю _source каждого документа в ответе и получаю информацию из метаданных, проверяя ввод. Ваш ответ обеспечивает оптимизацию моего текущего метода, потому что я бы добавил результат рядом с полем предложения и вернул его, отфильтровав совпадающее поле предложения, но оно все еще кажется мне довольно неэффективным ... Я хотел бы иметь выводить в ответ options и не искать его в _source каждого документа. Но я не уверен, что это возможно. - person WhiteFangs; 16.08.2017
comment
Я бы сказал, что вы разрабатываете свой индекс таким образом, чтобы получить желаемый результат по первому индексу массива результатов. Поэтому, если у вас есть несколько выходных данных прямо сейчас, разделите их на несколько индексов, чтобы вы всегда получали наилучшее совпадение по первому индексу документа с наивысшим рейтингом. Я надеюсь, что этот ответ наиболее близок к вашему вопросу. Буду признателен, если вы примете это как ответ на свой вопрос. Спасибо. - person mayankchutani; 20.08.2017
comment
Я думаю, что вы правы и старого способа получения результатов (я бы сказал, что идеальное решение в моем конкретном случае) больше не существует. - person WhiteFangs; 21.08.2017
comment
Спасибо. Рад, что смог помочь. - person mayankchutani; 21.08.2017