Elasticsearch Ngrams: неожиданное поведение для автозаполнения - PullRequest
2 голосов
/ 09 мая 2019

Вот упрощение того, что у меня есть:

PUT my_index
{
  "settings": {
    "analysis": {
      "analyzer": {
        "autocomplete": {
          "tokenizer": "autocomplete",
          "filter": [
            "lowercase"
          ]
        },
        "autocomplete_search": {
          "tokenizer": "lowercase"
        }
      },
      "tokenizer": {
        "autocomplete": {
          "type": "edge_ngram",
          "min_gram": 2,
          "max_gram": 10,
          "token_chars": [
            "letter"
          ]
        }
      }
    }
  },
  "mappings": {
    "_doc": {
      "properties": {
        "title": {
          "type": "text",
          "analyzer": "autocomplete",
          "search_analyzer": "autocomplete_search"
        }
      }
    }
  }
}

PUT my_index/_doc/1
{
  "title": "Quick Foxes" 
}

PUT my_index/_doc/2
{
  "title": "Quick Fuxes" 
}

PUT my_index/_doc/3
{
  "title": "Foxes Quick" 
}

PUT my_index/_doc/4
{
  "title": "Foxes Slow" 
}

Я пытаюсь найти Quick Fo для проверки автозаполнения:

 GET my_index/_search
    {
      "query": {
        "match": {
          "title": {
            "query": "Quick Fo", 
            "operator": "and"
          }
        }
      }
    }

Проблема в том, что этот запрос также возвращает Foxes Quick, где я ожидал "быстрых лис"

{
  "took": 3,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 2,
    "max_score": 0.5753642,
    "hits": [
      {
        "_index": "my_index",
        "_type": "_doc",
        "_id": "1",
        "_score": 0.5753642,
        "_source": {
          "title": "Quick Foxes"
        }
      },
      {
        "_index": "my_index",
        "_type": "_doc",
        "_id": "3",
        "_score": 0.5753642,
        "_source": {
          "title": "Foxes Quick"   <<<----- WHY???
        }
      }
    ]
  }
}

Что я могу настроить, чтобы я мог запросить классическое «автозаполнение», где «Quick Fo» наверняка не вернет «Foxes Quick» ..... а только «Quick Foxes»?

---- ДОПОЛНИТЕЛЬНАЯ ИНФОРМАЦИЯ -----------------------

Это сработало для меня:

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


PUT my_index1/_doc/1
{
  "text": "Quick Brown Fox" 
}

PUT my_index1/_doc/2
{
  "text": "Quick Frown Fox" 
}


PUT my_index1/_doc/3
{
  "text": "Quick Fragile Fox" 
}


GET my_index1/_search
{
  "query": {
    "match": {
      "text": {
        "query": "quick br", 
        "operator": "and"
      }
    }
  }
}

1 Ответ

3 голосов
/ 09 мая 2019

Проблема связана с вашим поисковым анализатором autocomplete_search , в котором вы используете токенайзер в нижнем регистре, поэтому ваш поисковый запрос Quick Fo будет разделен на 2 условия, quick и fo (обратите внимание на нижний регистр) и будут сопоставлены с токенами, сгенерированными с помощью autocomplete analyzer в ваших проиндексированных документах.

Теперь title Foxes Quick использует autocomplete analyzer и будет иметь как quick , так и fo токены, следовательно, он совпадает с токенами поискового запроса.

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

Пожалуйста, ознакомьтесь с официальным документом ES https://www.elastic.co/guide/en/elasticsearch/guide/master/_index_time_search_as_you_type.html о том, как реализовать автозаполнение, они также используют другой анализатор времени поиска, но есть определенное ограничение и не могут решить все варианты использования ( особенно, если у вас есть документы, подобные вашей ), поэтому я реализовал их, используя другой дизайн, основанный на бизнес-требованиях.

Надеюсь, я ясно объяснил, почему он возвращает второй документ в вашем случае.

РЕДАКТИРОВАТЬ: Также в вашем случае, IMO Префикс совпадения фразы будет более полезным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...