Elasticsearch: выигрыш с помощью Ngrams

У меня прямой вопрос, где я включил Ngram для частичных совпадений. Реализация работает хорошо, но результаты оценки не работают, как я надеялся. Я бы хотел, чтобы результаты моих оценок выглядели примерно так:

  • Ke:.1
  • Кев: .2
  • Кеви: .3
  • Кевин:.4

Вместо этого я получаю следующие результаты, где оценка одинакова, если есть совпадение для поля:

  • Ke:.4
  • Кев:.4
  • Кеви:.4
  • Кевин:.4

Настройки:

 settings: {
    analysis: {
      filter: {
        ngram_filter: {
          type: 'edge_ngram',
          min_gram: 2,
          max_gram: 15
        }
      },
      analyzer: {
        ngram_analyzer: {
          type: 'custom',
          tokenizer: 'standard',
          filter: [
            'lowercase',
            'ngram_filter'
          ]
        }
      }
    }
  }

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

mappings: [{
          name: 'voter',
          _all: {
                'type': 'string',
                'analyzer': 'ngram_analyzer',
                'search_analyzer': 'standard'
             },
             properties: {
                last: {
                   type: 'string',
                   required : true,
                   include_in_all: true,
                   analyzer: 'ngram_analyzer',
                   search_analyzer: 'standard'
                },
                first: {
                   type: 'string',
                   required : true,
                   include_in_all: true,
                   analyzer: 'ngram_analyzer',
                   search_analyzer: 'standard'
                },

             }

       }]

Запрос:

GET /user/_search
{
    "query": {
        "match": {
           "_all": {
               "query": "Ke",
               "operator": "and"

           }
        }
    }
}

1 ответ

Решение

Вы можете решить это, используя edgeNGram токенизатор вместо edgeNGram фильтр:

 settings: {
    analysis: {
      tokenizer: {
        ngram_tokenizer: {
          type: 'edge_ngram',
          min_gram: 2,
          max_gram: 15
        }
      },
      analyzer: {
        ngram_analyzer: {
          type: 'custom',
          tokenizer: 'ngram_tokenizer',
          filter: [
            'lowercase'
          ]
        }
      }
    }
  }

Причина этого заключается в том, что edgeNGram фильтр запишет термины для данного токена в той же позиции (почти как синонимы), в то время как edgeNGram tokenizer создаст токены, которые имеют разные позиции, что влияет на нормализацию длины и, следовательно, на оценку.

Обратите внимание, что это работает только в выпусках ES до версии 2.0, потому что составная оценка вычисляется из всех оценок токенов ngram, тогда как в ES 2.x оценивается только соответствующий токен.

Другие вопросы по тегам