Правильный способ поиска пользователей по частичному имени пользователя или имени с использованием токенизатора ngram в elasticsearch

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

Например:

input: okma
result: {"username": "alokmahor", "name": "Alok Singh Mahor"} // partial match in username

input: m90
result: {"username": "ram9012", "name": "Ram Singh"} // partial match in username

input: shn
result: {"username": "r2020", "name": "Krishna Kumar"} // partial match with name  

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

Я подписался на
https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-ngram-tokenizer.html
Как искать часть слова с помощью ElasticSearch

Мое решение

DELETE my_index

PUT my_index
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_analyzer": {
          "tokenizer": "my_tokenizer"
        }
      },
      "tokenizer": {
        "my_tokenizer": {
          "type": "ngram",
          "min_gram": 3,
          "max_gram": 3,
          "token_chars": [
            "letter",
            "digit"
          ]
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "username":   { "type": "text", "analyzer": "my_analyzer"  },
      "name":   { "type": "text", "analyzer": "my_analyzer"  } 
    }
  }
}


PUT /my_index/_doc/1
{
  "username": "alokmahor",
  "name": "Alok Singh Mahor"
}

PUT /my_index/_doc/2
{
  "username": "ram9012",
  "name": "Ram Singh"
}

PUT /my_index/_doc/3
{
  "username": "r2020",
  "name": "Krishna Kumar"
}

GET my_index/_search
{
"query": {
    "multi_match": {
      "query": "shn",
      "analyzer": "my_analyzer",
      "fields": ["username", "name"]
    }
  }
}

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

Вещи, которые не работают

// "sin" is not matching with "Singh" but "Sin" is matching and working.
GET my_index/_search
{
"query": {
    "multi_match": {
      "query": "sin",
      "analyzer": "my_analyzer",
      "fields": ["username", "name"]
    }
  }
}

person Alok Singh Mahor    schedule 07.01.2020    source источник
comment
Просто любопытно: вы улучшили создание индекса? Поиск имени пользователя работает с этой настройкой, мне интересно, улучшили ли вы его больше   -  person J. Doe    schedule 28.12.2020


Ответы (1)


Пожалуйста, предложите правильный путь

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

улучшение этого

Для проблемы вы указываете, где Sin совпадает, а sin - нет; это потому, что определенный анализатор не делает поиск нечувствительным к регистру. Для этого добавьте фильтр нижнего регистра в определение вашего анализатора, как показано ниже:

  "analyzer": {
    "my_analyzer": {
      "tokenizer": "my_tokenizer",
      "filter": [
        "lowercase"
      ]
    }
  }

Этот ответ может помочь вам понять больше при поиске без учета регистра.

person Nishant    schedule 07.01.2020