Игорь, доброго времени суток. Подскажите, пожалуйста.
Может я не так понял зачем нужен фильтр?
В запросе ниже основное слово запроса игнорируется и поиск идет уже по содержимому фильтров.
Сам массив фильтров формируется в цикле таким образом:
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" }}) - примерно в таком виде приходят.
А что вы ожидали, когда вы добавили этот фильтр?
Фильтровать или сортировать? Сортировка ничего фильтровать не должна, она просто определят какие записи появляются сначала и какие потом.
Вы не могли бы показать на примере, что не работает?
А как поле, по которому идет сортировка, проиндексировано?
Версия к слову у меня 2.3.3
GET /_search
{
"query": {
"filtered": {
"query": {
"match": {
"_all": "Ростов"
},
"filter":{
"and" : [{"match": {"some_info" : "Манчестер"}}]
}
}
}
},
"highlight": {
"fields": {
"*": {"require_field_match": false}
}
}
}
ввожу в поиске без фильтров - Ростов
выводятся 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"
}
}
]
}
Игорь, я в запросе наоборот хотел чтоб фильтр находил только документы вида
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, где ему и положено быть. Будьте осторожней со скобками и форматированием.