# Порядок слов в полнотекстном поиске

**URL:** <https://discuss.elastic.co/t/topic/310239>\
**Category:** Вопросы на русском языке\
**Created:** [July 21, 2022, 6:27am UTC](https://discuss.elastic.co/t/topic/310239 "2022-07-21T06:27:59Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Evgeny\_Antipin](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/evgeny_antipin/32/83050_2.png) [@Evgeny\_Antipin](https://discuss.elastic.co/u/Evgeny_Antipin)\
**Post date:** [July 21, 2022, 6:27am UTC](https://discuss.elastic.co/t/topic/310239/1 "2022-07-21T06:27:59Z")

</div>

Доброго дня.

Есть такой индекс:

```auto
{
    "ta": {
        "mappings": {
            "properties": {
                "address": {
                    "type": "text"
                },
                "obj_id": {
                    "type": "keyword"
                }
            }
        }
    }
}

```

В него грузятся адреса примерно в формате "Москва г, Центральная ул, дом 7, квартира 15".  
Нужно по адресу получать obj\_id. Строка для поиска может быть примерно такой  
"моск цент 7 15", т.е. пользователь вводит сокращенные данные.

Сейчас поиск выглядит так:

```auto
{
"size": 21,    
"query": {
        "bool": {
            "must": [
                {
                    "query_string": {
                        "query": "*моск* *цент* 7 15",
                        "fields": [
                            "address"
                        ]
                    }
                }
            ],
            "must_not": []
        }
    }
}

```

Полей на самом деле больше и запрос может быть сложнее, поэтому есть секция bool, но сейчас это не важно.  
В таком виде запрос вернет адреса:  
"Москва г, Центральная ул, дом 7, квартира 15"  
"Москва г, Центральная ул, дом 15, квартира 7"

Если ли возможность задать порядок слов при поиске?  
Т.е. если я задам  
"_моск_ _цент_ 7 15" - возвращается только "Москва г, Центральная ул, дом 7, квартира 15"  
"_моск_ _цент_ 15 7" - возвращается только "Москва г, Центральная ул, дом 15, квартира 7"?

---

<div class="post-metadata">

**Author:** ![pablissimo77](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/pablissimo77/32/108804_2.png) [@pablissimo77](https://discuss.elastic.co/u/pablissimo77)\
**Post date:** [July 25, 2022, 11:41am UTC](https://discuss.elastic.co/t/topic/310239/2 "2022-07-25T11:41:41Z")

</div>

Порядок слов учитывается только при поиске фразы. В данном случае нужно запрос заключать в кавычки и использовать параметр [phrase\_slop](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-query-string-query.html#query-string-top-level-params)

Такой запрос

```auto
{
  "query": {
    "bool": {
      "must": [
        {
          "query_string": {
            "query": "\"15 7\"",
            "fields": [
              "address"
            ],
            "phrase_slop": 1
          }
        }
      ],
      "must_not": []
    }
  }
}

```

вернёт только `"Москва г, Центральная ул, дом 15, квартира 7"`

---

<div class="post-metadata">

**Author:** ![Evgeny\_Antipin](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/evgeny_antipin/32/83050_2.png) [@Evgeny\_Antipin](https://discuss.elastic.co/u/Evgeny_Antipin)\
**Post date:** [July 27, 2022, 11:54am UTC](https://discuss.elastic.co/t/topic/310239/3 "2022-07-27T11:54:54Z")

</div>

Если взять в кавычки строку не работает полнотекстность.  
Например

```auto
"\"*моск* *цент* 7 15\""

```

уже не работает.  
Как это побороть?

---

<div class="post-metadata">

**Author:** ![pablissimo77](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/pablissimo77/32/108804_2.png) [@pablissimo77](https://discuss.elastic.co/u/pablissimo77)\
**Post date:** [July 28, 2022, 7:01am UTC](https://discuss.elastic.co/t/topic/310239/4 "2022-07-28T07:01:45Z")

</div>

`wildcard` в `match_phrase` не работает.  
Поэтому можно искать так:

```auto
{
  "query": {
    "bool": {
      "must": [
        {
          "query_string": {
            "query": "\"москва Центральная 7 15\"",
            "fields": [
              "address"
            ],
            "phrase_slop": 4
          }
        }
      ],
      "must_not": []
    }
  }
}

```

или

```auto
{
  "query": {
    "bool": {
      "must": [
        {
          "match_phrase": {
            "address": {
              "query": "москва Центральная 7 15",
              "slop": 4
            }
          }
        }
      ],
      "must_not": []
    }
  }
}

```

но для большего контроля лучше использовать [Span near query](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-span-near-query.html)

```auto
{
  "query": {
    "bool": {
      "must": [
        {
          "span_near": {
            "clauses": [
              {
                "span_multi": {
                  "match": {
                    "wildcard": {
                      "address": {
                        "value": "*моск*"
                      }
                    }
                  }
                }
              },
              {
                "span_multi": {
                  "match": {
                    "wildcard": {
                      "address": {
                        "value": "*цент*"
                      }
                    }
                  }
                }
              },
              {
                "span_term": {
                  "address": "7"
                }
              },
              {
                "span_term": {
                  "address": "15"
                }
              }
            ],
            "slop": 4,
            "in_order": true
          }
        }
      ],
      "must_not": []
    }
  }
}

```

Но я перед индексацией разбирал бы адрес на составляющие (город, улица, дом и т.д.) и помещал все в соответствующие поля. Тогда запросы делать было легче.

---

<div class="post-metadata">

**Author:** ![Evgeny\_Antipin](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/evgeny_antipin/32/83050_2.png) [@Evgeny\_Antipin](https://discuss.elastic.co/u/Evgeny_Antipin)\
**Post date:** [August 4, 2022, 11:00am UTC](https://discuss.elastic.co/t/topic/310239/5 "2022-08-04T11:00:54Z")

</div>

Спасибо, попробую.

---

<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:** [September 1, 2022, 11:01am UTC](https://discuss.elastic.co/t/topic/310239/6 "2022-09-01T11:01:08Z")

</div>

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