# Не ищет в индексе по половине слова

**URL:** https://discuss.elastic.co/t/topic/110423
**Category:** Вопросы на русском языке
**Created:** [December 5, 2017, 9:33pm UTC](https://discuss.elastic.co/t/topic/110423 "2017-12-05T21:33:39Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![Petr\_Sklyarov](https://avatars.discourse-cdn.com/v4/letter/p/87869e/32.png) [@Petr\_Sklyarov](https://discuss.elastic.co/u/Petr_Sklyarov)
#### Post date: [December 5, 2017, 9:33pm UTC](https://discuss.elastic.co/t/topic/110423/1 "2017-12-05T21:33:39Z")

</div>

Добрый день!  
Вопрос возник. В документе есть записи в поле title с значениями "Балтика №0", "Балтика №1" и тд  
Если подать на поиск слово "балтик" - то находит записи, а если, например, "балти" - то ничего не находит. Можете подсказать в чем проблема? Вот параметры создания документа:

> ```
> $params = [
> 'index' => $this->index,
> 'body' => [
> 'settings' => [
> 'analysis' => [
> 'tokenizer' => 'standard',
> 'filter' => [
> 'ru_stop' => [
> 'type' => 'stop',
> 'stopwords' => '_russian_'
> ],
> 'ru_stemmer' => [
> 'type' => 'stemmer',
> 'language' => 'russian'
> ],
> 'possessive_english' => [
> 'type' => 'stemmer',
> 'language' => 'possessive_english'
> ],
> 'english' => [
> 'type' => 'stemmer',
> 'language' => 'english'
> ],
> ],
> 'analyzer' => [
> 'default' => [
> 'tokenizer' => 'standard',
> 'filter' => ['lowercase', 'ru_stop', 'ru_stemmer', 'possessive_english', 'english']
> ]
> ]
> ]
> ],
> ]
> ];
> 
> ```

А ищу слово так:

> $paramSearch['body']['query']['match']['title'] = 'балти';

Заранее спасибо всем, кто сможет помочь!

---

<div class="post-metadata">

### Author: ![Igor\_Motov](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/igor_motov/32/45193_2.png) [@Igor\_Motov](https://discuss.elastic.co/u/Igor_Motov)
#### Post date: [December 6, 2017, 5:37pm UTC](https://discuss.elastic.co/t/topic/110423/2 "2017-12-06T17:37:26Z")

</div>

Давайте посмотрим какие токены получаются в каждом случае. Запускаем анализатор на документе:

```auto
GET _analyze
{
  "tokenizer": "standard",
  "filter": [
    "lowercase",
    {
      "type": "stop",
      "stopwords": "_russian_"
    },
    {
      "type": "stemmer",
      "language": "russian"
    },
    {
      "type": "stemmer",
      "language": "possessive_english"
    },
    {
      "type": "stemmer",
      "language": "english"
    }
  ],
  "text": "Балтика №0, Балтика №1"
}

```

Получаем токены `балтик`, `0`, `балтик`, `1`. Теперь запускаем анализатор на вашем запросе, получаем `балт`. Токен из вашего запроса не совпадает ни с одним токеном из вашего документа, и как результат вы ничего не находите.

---

<div class="post-metadata">

### Author: ![Petr\_Sklyarov](https://avatars.discourse-cdn.com/v4/letter/p/87869e/32.png) [@Petr\_Sklyarov](https://discuss.elastic.co/u/Petr_Sklyarov)
#### Post date: [December 6, 2017, 7:40pm UTC](https://discuss.elastic.co/t/topic/110423/3 "2017-12-06T19:40:47Z")

</div>

а как то можно сделать что бы находилось? неужели es не может того, что может простой MySQL LIKE ?

---

<div class="post-metadata">

### Author: ![Igor\_Motov](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/igor_motov/32/45193_2.png) [@Igor\_Motov](https://discuss.elastic.co/u/Igor_Motov)
#### Post date: [December 6, 2017, 9:22pm UTC](https://discuss.elastic.co/t/topic/110423/4 "2017-12-06T21:22:21Z")

</div>

Может, только вам надо решить, что вам нужно - простой MySQL LIKE или стемминг. Или вы будете искать и так и так.

---

<div class="post-metadata">

### Author: ![Petr\_Sklyarov](https://avatars.discourse-cdn.com/v4/letter/p/87869e/32.png) [@Petr\_Sklyarov](https://discuss.elastic.co/u/Petr_Sklyarov)
#### Post date: [December 7, 2017, 7:01am UTC](https://discuss.elastic.co/t/topic/110423/5 "2017-12-07T07:01:06Z")

</div>

и так и так нужно 🙂 Можете сказать, как это сделать можно?

---

<div class="post-metadata">

### Author: ![Igor\_Motov](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/igor_motov/32/45193_2.png) [@Igor\_Motov](https://discuss.elastic.co/u/Igor_Motov)
#### Post date: [December 7, 2017, 8:15pm UTC](https://discuss.elastic.co/t/topic/110423/6 "2017-12-07T20:15:47Z")

</div>

Если главное - скорость поиска, то можно проиндексировать с помощью [N-gram](https://www.elastic.co/guide/en/elasticsearch/reference/6.0/analysis-ngram-tokenfilter.html) фильтра:

```auto
DELETE test_index
PUT test_index
{
  "settings": {
    "analysis": {
      "filter": {
        "ru_stop": {
          "type": "stop",
          "stopwords": "_russian_"
        },
        "ru_stem": {
          "type": "stemmer",
          "language": "russian"
        },
        "en_stem": {
          "type": "stemmer",
          "language": "english"
        },
        "en_pos": {
          "type": "stemmer",
          "language": "possessive_english"
        },
        "ngram": {
          "type": "edgeNGram",
          "min_gram": 1,
          "max_gram": 20
        }
      }, 
      "analyzer": {
        "my_stemmer": {
          "type": "custom",
          "tokenizer": "standard",
          "filter": ["lowercase", "ru_stop", "ru_stem", "en_pos"]
        },
        "my_ngram_index": {
          "type": "custom",
          "tokenizer": "standard",
          "filter": ["lowercase", "ru_stop", "ngram"]
        },
        "my_ngram_search": {
          "type": "custom",
          "tokenizer": "standard",
          "filter": ["lowercase"]
        }
      }
    }
  },
  "mappings": {
    "doc": {
      "properties": {
        "text": {
          "type": "text",
          "analyzer": "my_stemmer",
          "fields": {
            "ngrams": {
              "type": "text",
              "analyzer": "my_ngram_index",
              "search_analyzer": "my_ngram_search"
            }
          }
        }
      }
    }
  }
}

POST /test_index/doc/_bulk?refresh
{ "index" : { "_id" : "1" } }
{ "text" : "Балтика №0, Балтика №1" }
{ "index" : { "_id" : "2" } }
{ "text" : "Lion's Head или Lions" }

GET test_index/doc/_search
{
  "query": {
    "multi_match": {
      "query": "Балтика",
      "fields": ["text", "text.ngrams"]
    }
  }
}

GET test_index/doc/_search
{
  "query": {
    "multi_match": {
      "query": "Балтикой",
      "fields": ["text", "text.ngrams"]
    }
  }
}

GET test_index/doc/_search
{
  "query": {
    "multi_match": {
      "query": "Бал",
      "fields": ["text", "text.ngrams"]
    }
  }
}

GET test_index/doc/_search
{
  "query": {
    "multi_match": {
      "query": "lion",
      "fields": ["text", "text.ngrams"]
    }
  }
}

```

Если заботить размер индекса и не волнует скорость поиска или требуемая память - то можно искать с помощью [`match_phrase_prefix`](https://www.elastic.co/guide/en/elasticsearch/reference/6.0/query-dsl-prefix-query.html) или [`prefix`](https://www.elastic.co/guide/en/elasticsearch/reference/6.0/query-dsl-prefix-query.html).

```auto
DELETE test_index
PUT test_index
{
  "settings": {
    "analysis": {
      "filter": {
        "ru_stop": {
          "type": "stop",
          "stopwords": "_russian_"
        },
        "ru_stem": {
          "type": "stemmer",
          "language": "russian"
        },
        "en_stem": {
          "type": "stemmer",
          "language": "english"
        },
        "en_pos": {
          "type": "stemmer",
          "language": "possessive_english"
        }
      }, 
      "analyzer": {
        "my_stemmer": {
          "type": "custom",
          "tokenizer": "standard",
          "filter": ["lowercase", "ru_stop", "ru_stem", "en_pos"]
        }
      }
    }
  },
  "mappings": {
    "doc": {
      "properties": {
        "text": {
          "type": "text",
          "analyzer": "my_stemmer",
          "fields": {
            "standard": {
              "type": "text",
              "analyzer": "standard"
            }
          }
        }
      }
    }
  }
}

POST /test_index/doc/_bulk?refresh
{ "index" : { "_id" : "1" } }
{ "text" : "Балтика №0, Балтика №1" }
{ "index" : { "_id" : "2" } }
{ "text" : "Lion's Head или Lions" }

GET test_index/doc/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "match": {
            "text": "Бал"
          }
        },
        {
          "match_phrase_prefix": {
            "text.standard": "Бал"
          }
        }
      ]
    }
  }
}

```

---

<div class="post-metadata">

### Author: ![Petr\_Sklyarov](https://avatars.discourse-cdn.com/v4/letter/p/87869e/32.png) [@Petr\_Sklyarov](https://discuss.elastic.co/u/Petr_Sklyarov)
#### Post date: [December 11, 2017, 10:01am UTC](https://discuss.elastic.co/t/topic/110423/7 "2017-12-11T10:01:19Z")

</div>

> [@Igor\_Motov](#):
>
> ngram

Спасибо, Вам огромное!

---

<div class="post-metadata">

### Author: ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)
#### Post date: [January 8, 2018, 10:01am UTC](https://discuss.elastic.co/t/topic/110423/8 "2018-01-08T10:01:50Z")

</div>

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.
