Автозаполнение в Elasticsearch с предложением следующего слова - PullRequest
0 голосов
/ 23 мая 2018

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

Мои индексированные строки, например, для:

  • "Developpeur Java"
  • "Developpeur C #"
  • "Je suis Developpeur"
  • "Je suis écrivan"
  • "Il est Developpeur C ++"

Для ввода "develo", я хочу в качестве вывода:

  • "Developpeur Java"
  • "Developpeur Java"
  • "Developpeur C #"
  • "Developpeur C ++"

Для ввода "veloppeur ", я хочу в качестве вывода:

  • "veloppeur Java"
  • "veloppeur C # "
  • "veloppeur C ++"

для ввода "suis", я хочу выводить:

  • "suis Developpeur"
  • "suis écrivan"

Я пытался получитьэто с использованием подсказки завершения:

вот эластичный поиск, который я использую:

"number": "6.2.2",
"build_hash": "10b1edd",
"build_date": "2018-02-16T19:01:30.685723Z",
"build_snapshot": false,
"lucene_version": "7.2.1",
"minimum_wire_compatibility_version": "5.6.0",
"minimum_index_compatibility_version": "5.0.0"

отображение:

{
"settings": {
    "number_of_shards": "1",
    "analysis": {
        "filter": {
            "prefix_filter": {
                "type": "edge_ngram",
                "min_gram": 1,
                "max_gram": 20
            },
            "ngram_filter": {
                "type": "nGram",
                "min_gram": "3",
                "max_gram": "3"
            },
            "synonym_filter": {
                "type": "synonym",
                "synonyms": [
                    "hackwillbereplacedatindexcreation,hackwillbereplacedatindexcreation"
                ]
            },
            "french_stop": {
                "type": "stop",
                "stopwords": "french"
            }
        },
        "analyzer": {
            "word": {
                "type": "custom",
                "tokenizer": "standard",
                "filter": [
                    "lowercase",
                    "asciifolding",
                    "french_stop"
                ],
                "char_filter": []
            },
            "prefix": {
                "type": "custom",
                "tokenizer": "standard",
                "filter": [
                    "lowercase",
                    "asciifolding",
                    "synonym_filter",
                    "prefix_filter"
                ],
                "char_filter": []
            },
            "ngram_with_synonyms": {
                "type": "custom",
                "tokenizer": "standard",
                "filter": [
                    "lowercase",
                    "asciifolding",
                    "synonym_filter",
                    "ngram_filter"
                ],
                "char_filter": []
            },
            "ngram": {
                "type": "custom",
                "tokenizer": "standard",
                "filter": [
                    "lowercase",
                    "asciifolding",
                    "ngram_filter"
                ],
                "char_filter": []
            }
        }
    }
},
"mappings": {
    "training": {
        "properties": {
            "id": {
                "type": "text",
                "index": false
            },
            "label": {
                "type": "text",
                "index_options": "docs",
                "copy_to": "full_label",
                "analyzer": "word",
                "fields": {
                    "prefix": {
                        "type": "text",
                        "index_options": "docs",
                        "analyzer": "prefix",
                        "search_analyzer": "word"
                    },
                    "ngram": {
                        "type": "text",
                        "index_options": "docs",
                        "analyzer": "ngram_with_synonyms",
                        "search_analyzer": "ngram"
                    }
                }
            },
            "labelSuggest": {
                "type": "completion",
                "analyzer": "word"
            },
        }
    }
}

Затем, когда я создаю индекс с моими данными, ясделать это (это тело пут-колла, сделанного к API API,Для этого я использую pyhon):

body = {
    "label": r["title"],
    "labelSuggest": {
        "input": r["title"].ngrams()
    },
    "weight": 1.
}

r ["title"]. Ngrams () получает все ngram из заголовка.Например: «Биотехнология исследования развития» будет давать: «Развитие», «Исследования», «Биотехнология», «Исследования развития», «Биотехнология исследования» и «Биотехнология исследования развития»

, а затем называть suggseter, Ido:

   POST  http://localhost:9200/training/_search?pretty
{
    "suggest": {
        "labelSuggest": {
            "text": "developpeur",
            "completion": {
                "field": "labelSuggest",
                "skip_duplicates": true

            }
        }
    }
}

Результат:

{
    "text": "développement",
    "_index": "activity_20180518092449",
    "_type": "activity",
    "_id": "2031ce8b-6589-3270-afdf-7901aa21efa1",
    "_score": 1,
    "_source": {
        "id": "2031ce8b-6589-3270-afdf-7901aa21efa1",
        "name": "development research biotech",
        "labelSuggest": [
            "development",
            "research",
            "biotech",
            "development research",
            "research biotech",
            "development research biotech"
        ]
    }

Но я хочу кое-что, что дает мне: "развитие", "исследование развития" и "биотехнология исследования развития" (предположим, что мы толькоиметь этот документ в качестве входных данных)

Что не так с отображением / запросом, который я делаю?Это правильный способ сделать это?Я надеюсь, что мой вопрос ясен.Я много об этом искал напрасно.

Заранее спасибо

1 Ответ

0 голосов
/ 23 мая 2018

Прежде всего, Ngram не будет делать то, что вы говорите.

this:

"ngram_filter": {
            "type": "nGram",
            "min_gram": "3",
            "max_gram": "3"
        },

будет делать это из "veloppeur Java "-> dev, eve, vel, elo... и так далее.

Проверьте документацию здесь: Ngram Tokenizer

Второе ... для получения желаемого результата я просто использую один пользовательский анализатор с фильтрами "icu_folding "и" engram "и символ пробела.Теперь инграмма я начну с 2 и максимум 20-25.

Это сгенерирует список токенов, подобных этому, из «Developpeur Java» -> de, dev, deve, devel, develo, developp ,veloppe, devellopeu, developper .. и т. Д.

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

ОБНОВЛЕНИЕ: попробуйте использовать это:

"suggester": {
"type": "custom",
"tokenizer": "whitespace",
"filter": ["my_ngram_filter", "icu_folding"],
"char_filter": []
}
"my_ngram_filter" is: "my_ngram_filter": {
    "type": "edge_ngram",
    "min_gram": "2",
    "max_gram": "20"
}

Тогда отображение на поле должно выглядеть следующим образом:

"labelSuggest": {
            "type": "text",
            "analyzer": "suggester"
        }

Затем выполните простой поиск

  {
  "query": {
    "term": {
      "labelSuggest": "dev" 
    }
   }
  }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...