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

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

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

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

Сам массив фильтров формируется в цикле таким образом:
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}
					}
		}
	}

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

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

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

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

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

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

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

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

Версия к слову у меня 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": "Манчестер находится в Англии"
}
}

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

    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
                                    }
                                });

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

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"
      }
    }
  ]
}
1 Like

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

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"
    }
  }
			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 только одно упоминание по filtered , потому изначально filter внутрь и поместил, хотел как в апи указано сделать.

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

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

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

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