Elasticsearch: почему точное совпадение имеет меньшую оценку, чем частичное совпадение - PullRequest
1 голос
/ 04 марта 2020

мой вопрос

Я ищу слово form, но слово с точным соответствием form не является первым в результате. Есть ли способ решить эту проблему?

мой поисковый запрос

{
  "query": {
    "match": {
      "word": "form"
    }
  }
}

результат

word             score
--------------------------
formulation      10.864353
formaldehyde     10.864353
formless         10.864353
formal   10.84412
formerly         10.84412
forma    10.84412
formation        10.574185
formula          10.574185
formulate        10.574185
format   10.574185
formally         10.574185
form     10.254687
former   10.254687
formidable       10.254687
formality        10.254687
formative        10.254687
ill-formed       10.054999
in form          10.035862
pro forma        9.492243

POST my_index / _analyze

Слово form в поиске имеет только один токен form.

В индексе form токены являются ["f", "fo", "for", "form"]; formulation токены: ["f", "fo", ..., "Formtio", "Formulation"].

my config

filter

        "edgengram_filter": {
          "type": "edge_ngram",
          "min_gram": 1,
          "max_gram": 20
        }

анализатор

      "analyzer": {
        "abc_vocab_analyzer": {
          "type": "custom",
          "tokenizer": "standard",
          "filter": [
            "keyword_repeat",
            "lowercase",
            "asciifolding",
            "edgengram_filter",
            "unique"
          ]
        },
        "abc_vocab_search_analyzer": {
          "type": "custom",
          "tokenizer": "standard",
          "filter": [
            "keyword_repeat",
            "lowercase",
            "asciifolding",
            "unique"
          ]
        }
      }

отображение

        "word": {
          "type": "text",
          "analyzer": "abc_vocab_analyzer",
          "search_analyzer": "abc_vocab_search_analyzer"
        }

Ответы [ 3 ]

0 голосов
/ 04 марта 2020

Вы получаете результат так, как видите, потому что вы внедрили фильтр edge-ngram, а form - это подстрока слов, похожих на него. В основном в инвертированном индексе он также будет хранить идентификаторы документов, которые содержат formulation, formal et c.

Таким образом, ваша релевантность также вычисляется таким образом. Вы можете обратиться к этой ссылке, и я бы специально предложил вам go через разделы Default Similarity и BM25. Хотя текущее сходство по умолчанию BM25, эта ссылка поможет вам понять, как работает оценка.

Вам потребуется создать еще одно поле родного брата, которое вы можете применить в предложении must. Вы можете go вперед и создать подполе keyword с помощью Term Query, но вы должны быть осторожны с учетом регистра.

Вместо этого, как уже упоминалось @Val, вы можете создать одноуровневое поле text со стандартным анализатором.

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

   {
    "word":{
      "type": "text",
      "analyzer": "abc_vocab_analyzer",
      "search_analyzer": "abc_vocab_search_analyzer"
      "fields":{
        "standard":{
          "type": "text"
        }
      }
    }
  }

Запрос:

POST <your_index_name>/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "word": "form"
          }
        }
      ],
      "should": [                          <---- Note this
        {
          "match": {
            "word.standard": "form"
          }
        }
      ]
    }
  }
}

Дайте мне знать, если это поможет!

0 голосов
/ 04 марта 2020

Выглядит как проблема в вашем пользовательском анализаторе, я создал свой собственный анализатор autocomplete, который использует фильтры edge_ngram и lowercase, и он отлично работает для меня по вашему запросу, а возвращает мне точное совпадение сверху и вот как работает Elasticsearch, у точных совпадений всегда больше очков. , поэтому нет необходимости явно создавать другое поле и увеличивать его, поскольку Elasticsearch по умолчанию повышает точное совпадение при совпадении токенов.

Индекс по умолчанию

{
  "settings": {
    "analysis": {
      "filter": {
        "autocomplete_filter": {
          "type": "edge_ngram",
          "min_gram": 1,
          "max_gram": 10
        }
      },
      "analyzer": {
        "autocomplete": { 
          "type": "custom",
          "tokenizer": "standard",
          "filter": [
            "lowercase",
            "autocomplete_filter"
          ]
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "analyzer": "autocomplete", 
        "search_analyzer": "standard" 
      }
    }
  }
}

Индекс несколько дел c

{
   "title" : "formless"
}

{
   "title" : "form"
}

{
   "title" : "formulation"
}

Поисковый запрос в поле title, как указано в вопросе

{
  "query": {
    "match": {
      "title": "form"
    }
  }
}

Результат поиска с точным соответствием с наибольшим количеством баллов

"hits": [
         {
            "_index": "so-60523240-score",
            "_type": "_doc",
            "_id": "1",
            "_score": 0.16410133,
            "_source": {
               "title": "form"
            }
         },
         {
            "_index": "so-60523240-score",
            "_type": "_doc",
            "_id": "2",
            "_score": 0.16410133,
            "_source": {
               "title": "formulation"
            }
         },
         {
            "_index": "so-60523240-score",
            "_type": "_doc",
            "_id": "3",
            "_score": 0.16410133,
            "_source": {
               "title": "formaldehyde"
            }
         },
         {
            "_index": "so-60523240-score",
            "_type": "_doc",
            "_id": "4",
            "_score": 0.16410133,
            "_source": {
               "title": "formless"
            }
         }
      ]
0 голосов
/ 04 марта 2020

Поскольку ваш тип для этого поля - текст, это означает, что ES выполнит полнотекстовый поиск в этом поле. И процесс поиска ES - это своего рода поиск результатов, наиболее похожих на слово, которое вы дали.
Чтобы точно найти слово "форма", измените метод поиска на match_phrase
Кроме того, вы также можете прочитать статьи ниже, чтобы узнать подробнее о различных методах поиска ES: https://www.cnblogs.com/yjf512/p/4897294.html https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-match-query-phrase.html

...