# Фильтры перекрывают собой основное слово по которому идет поиск

**URL:** <https://discuss.elastic.co/t/topic/77972>\
**Category:** Вопросы на русском языке\
**Created:** [March 9, 2017, 11:51am UTC](https://discuss.elastic.co/t/topic/77972 "2017-03-09T11:51:01Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![whispersofdew](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/whispersofdew/32/11067_2.png) [@whispersofdew](https://discuss.elastic.co/u/whispersofdew)\
**Post date:** [March 9, 2017, 11:51am UTC](https://discuss.elastic.co/t/topic/77972/1 "2017-03-09T11:51:01Z")

</div>

Игорь, доброго времени суток. Подскажите, пожалуйста.

Может я не так понял зачем нужен фильтр?

В запросе ниже основное слово запроса игнорируется и поиск идет уже по содержимому фильтров.

Сам массив фильтров формируется в цикле таким образом:  
filterParams.push(JSON.parse('{"match": {' + JSON.stringify(value.path) + ' : '+ JSON.stringify(value.value) + '}}'));

```
  {
	    from:(from)?from:page*pagingLimit,
    size:pagingLimit,
    
	sort: sortParams,
		query: {
		    filtered: {
			query: {
				    match: {
					_all: searchTerm
				},
            filter:{
                and : filterParams
            }
			}
		    }
		},
		highlight: {
			fields: {
				"*": {require_field_match: false}
					}
		}
	}
```

---

<div class="post-metadata">

**Author:** ![whispersofdew](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/whispersofdew/32/11067_2.png) [@whispersofdew](https://discuss.elastic.co/u/whispersofdew)\
**Post date:** [March 9, 2017, 11:59am UTC](https://discuss.elastic.co/t/topic/77972/2 "2017-03-09T11:59:35Z")

</div>

кстати в этом же запросе еще и в сортировке проблема: по asc фильтрует как нужно, а вот по desc - если слов несколько, то фильтровать будет по последнему. что выглядит коряво и пока не понял причину.

sortParams.push({ \_score: { order: "desc" }}) - примерно в таком виде приходят.

---

<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:** [March 9, 2017, 12:56pm UTC](https://discuss.elastic.co/t/topic/77972/3 "2017-03-09T12:56:17Z")

</div>

> [@whispersofdew](#):
>
> В запросе ниже основное слово запроса игнорируется и поиск идет уже по содержимому фильтров.

А что вы ожидали, когда вы добавили этот фильтр?

> [@whispersofdew](#):
>
> кстати в этом же запросе еще и в сортировке проблема: по asc фильтрует как нужно, а вот по desc - если слов несколько, то фильтровать будет по последнему.

Фильтровать или сортировать? Сортировка ничего фильтровать не должна, она просто определят какие записи появляются сначала и какие потом.

---

<div class="post-metadata">

**Author:** ![whispersofdew](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/whispersofdew/32/11067_2.png) [@whispersofdew](https://discuss.elastic.co/u/whispersofdew)\
**Post date:** [March 9, 2017, 12:59pm UTC](https://discuss.elastic.co/t/topic/77972/4 "2017-03-09T12:59:27Z")

</div>

1. Я ожидал что выборка по  
match: {  
\_all: searchTerm  
},  
останется, но будет отфильтрована и уберется все лишнее, что не попадает под условия фильтра.

2. Все верно, извиняюсь за опечатку, по второму вопросу речь именно о сортировке. Она у меня тоже странно отрабатывает.  
Например если сортирую по алфавиту и будет 2 варианта "апельсин дерево" и "дерево апельсин" - то при desc сортировать будет по второму слову.

---

<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:** [March 9, 2017, 1:05pm UTC](https://discuss.elastic.co/t/topic/77972/5 "2017-03-09T13:05:33Z")

</div>

> [@whispersofdew](#):
>
> останется, но будет отфильтрована и уберется все лишнее, что не попадает под условия фильтра.

Вы не могли бы показать на примере, что не работает?

> [@whispersofdew](#):
>
> Например если сортирую по алфавиту и будет 2 варианта "апельсин дерево" и "дерево апельсин" - то при desc сортировать будет по второму слову.

А как поле, по которому идет сортировка, проиндексировано?

---

<div class="post-metadata">

**Author:** ![whispersofdew](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/whispersofdew/32/11067_2.png) [@whispersofdew](https://discuss.elastic.co/u/whispersofdew)\
**Post date:** [March 9, 2017, 3:08pm UTC](https://discuss.elastic.co/t/topic/77972/6 "2017-03-09T15:08:13Z")

</div>

Версия к слову у меня 2.3.3

```
GET /_search
{
		"query": {
		    "filtered": {
			"query": {
				    "match": {
					"_all": "Ростов"
				},
            "filter":{
                "and" : [{"match": {"some_info" : "Манчестер"}}]
            }
			}
		    }
		},
		"highlight": {
			"fields": {
				"*": {"require_field_match": false}
					}
    }
}

```

ввожу в поиске без фильтров - Ростов

выводятся 2 строки

1. Ростов на Дону
2. Ростов Великий

Далее дополняю запрос фильтрами. В основной запрос отправляю все тот же Ростов, а в фильтры добавляю Манчестер. В итоге в результат поиска выводится 3 строки про Манчестер и ни одной про Ростов.

1. В Манчестере холодно
2. Манчестер находится в Англии
3. Манчестер не столица

{  
"\_index": "world",  
"\_type": "test\_city",  
"\_id": "15cce6e3556bfaf82d7ae0b542e88fabc22d43d1",  
"\_score": 2.4339414,  
"\_timestamp": 1486566592347,  
"\_source": {  
"city": "Манчестер"  
"some\_info": "Манчестер находится в Англии"  
}  
}

Заметил, что с фильтрами еще и без хайлайтов возвращает.

---

<div class="post-metadata">

**Author:** ![whispersofdew](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/whispersofdew/32/11067_2.png) [@whispersofdew](https://discuss.elastic.co/u/whispersofdew)\
**Post date:** [March 9, 2017, 3:15pm UTC](https://discuss.elastic.co/t/topic/77972/7 "2017-03-09T15:15:54Z")

</div>

```
    jsonObj [someName] = {type: currentType, analyzer: "english", store: "yes",
            fields: {
                raw: { 
                    type: "string",
                    index: "not_analyzed"
                }
            }
    };

```

В данном случае проблема с сортировкой стрингов.  
До дат и нумериков толком не дошел.

```
return elasticClient.indices.putMapping({
                                    index : myIndex,
                                    type : myType,
                                    body : {
                                        properties : jsonObj
                                    }
                                });
```

---

<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:** [March 10, 2017, 4:54am UTC](https://discuss.elastic.co/t/topic/77972/8 "2017-03-10T04:54:54Z")

</div>

Во-первых, `filter` должен находиться на том же уровне, что и `query`, а не внутри его. Во-вторых, если вы хотите отфильтровать фильтром, то он должен быть завернут в `not`, а не в `and`. Другими словами, такой запрос работает:

```auto
DELETE test
PUT test
{
  "mappings": {
    "doc": {
      "properties": {
        "some_info": {
          "type": "string",
          "fields": {
            "raw": {
              "type": "string"
              , "index": "not_analyzed"
            }
          }
        }
      }
    }
  }
}
PUT test/doc/1
{
  "some_info": "Ростов на Дону"
}

PUT test/doc/2
{
  "some_info": "Ростов Великий"
}

PUT test/doc/3
{
  "some_info": "В Манчестере холодно"
}

PUT test/doc/4
{
  "some_info": "Манчестер находится в Англии"
}

POST test/doc/_search
{
  "query": {
    "filtered": {
      "query": {
        "match": {
          "_all": "Ростов"
        }
      },
      "filter": {
        "not": {
          "match": {
            "some_info": "Манчестер"
          }
        }
      }
    }
  },
  "highlight": {
    "fields": {
      "*": {
        "require_field_match": false
      }
    }
  },
  "sort": [
    {
      "some_info.raw": {
        "order": "desc"
      }
    }
  ]
}

```

---

<div class="post-metadata">

**Author:** ![whispersofdew](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/whispersofdew/32/11067_2.png) [@whispersofdew](https://discuss.elastic.co/u/whispersofdew)\
**Post date:** [March 10, 2017, 7:56am UTC](https://discuss.elastic.co/t/topic/77972/9 "2017-03-10T07:56:45Z")

</div>

Игорь, я в запросе наоборот хотел чтоб фильтр находил только документы вида

PUT test/doc/5  
{  
"some\_info": "Манчестер и Ростов"  
}

Т.е. чтоб он отфильтровал только то, где есть и основной запрос, и то что в фильтр пришло.  
Причем фильтров может прийти несколько.

Что-то вроде

```
POST test/doc/_search
{
  "query": {
    "filtered": {
      "query": {
        "match": {
          "_all": "Ростов"
        }
      },
      "filter": {
        "and": [{"match": {"some_info" : "Манчестер"}}]
        }
      
    }
  },
  "highlight": {
    "fields": {
      "*": {
        "require_field_match": false
      }
    }
  },
  "sort": [
    {
      "some_info.raw": {
        "order": "desc"
      }
    }
  ]
}

```

Так же сразу хотел спросить про даты и нумерики - их структуру так же надо при создании индекса описать?

```
  "fields": {
    "raw": {
      "type": "string"
      , "index": "not_analyzed"
    }
  }
```

---

<div class="post-metadata">

**Author:** ![whispersofdew](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/whispersofdew/32/11067_2.png) [@whispersofdew](https://discuss.elastic.co/u/whispersofdew)\
**Post date:** [March 10, 2017, 9:09am UTC](https://discuss.elastic.co/t/topic/77972/10 "2017-03-10T09:09:06Z")

</div>

```
			query: {
			    filtered: {
    				query: {
        				    match: {
        					_all: "Ростов"
        				}
    				}
			    },
                filter:{
                    and : [{match: {some_info : "Манчестер"}}]
                }
			},
			highlight: {
				fields: {
					"*": {require_field_match: false}
						}
			},

```

в js возвращает **failed to parse search source. expected field name but got [START\_OBJECT]**. при том что точно такой же, но с кавычками стандартный для кибаны запрос, отрабатывает корректно.  
если фильтры убрать - Ростов находится и в js.

Эх.

В [АПИ для js](https://www.elastic.co/guide/en/elasticsearch/client/javascript-api/current/api-reference-2-3.html) только одно упоминание по **filtered** , потому изначально filter внутрь и поместил, хотел как в апи указано сделать.

---

<div class="post-metadata">

**Author:** ![whispersofdew](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/whispersofdew/32/11067_2.png) [@whispersofdew](https://discuss.elastic.co/u/whispersofdew)\
**Post date:** [March 10, 2017, 10:50am UTC](https://discuss.elastic.co/t/topic/77972/11 "2017-03-10T10:50:27Z")

</div>

А вот так начало работать - просто переставил объект **filter**

```
			query: {
			    filtered: {
			        
                    filter:{
                        and: filterParams
                    },
    				query: {
        				    match: {
        					_all: searchTerm
        				}
    				}
			    }
			},
			highlight: {
				fields: {
					"*": {require_field_match: false}
						}
			},
			sort: sortParams
```

---

<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:** [March 11, 2017, 5:44pm UTC](https://discuss.elastic.co/t/topic/77972/12 "2017-03-11T17:44:49Z")

</div>

> [@whispersofdew](#):
>
> просто переставил объект filter

Вы не просто его переставили, вы поставили его во внутрь `filtered`, где ему и положено быть. Будьте осторожней со скобками и форматированием.

---

<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:** [April 8, 2017, 5:45pm UTC](https://discuss.elastic.co/t/topic/77972/13 "2017-04-08T17:45:11Z")

</div>

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