Проблемы с Elasticsearch на запрос
При добавлении термина к моему запросу вместо фильтра я получаю 0 граней. К вашему сведению, я использую драгоценный камень с Руби.
Вот мой код модели с отображением:
class Property < ActiveRecord::Base
include Tire::Model::Search
include Tire::Model::Callbacks
has_and_belongs_to_many :tags
mapping do
indexes :id, type: 'integer'
indexes :status
indexes :refno, type: 'integer'
indexes :name, :analyzer => 'snowball', :boost => 100
indexes :description
indexes :tags, type: 'object',
properties: {
name: { type: 'multi_field',
fields: {
name: { type: 'string', analyzer: 'snowball' },
exact: { type: 'string', index: 'not_analyzed' }
}
}
}
end
def to_indexed_json
to_json( include: {
tags: { only: [:name] },
})
end
Тогда вот метод поиска
def self.search(params={})
tire.search(page: params[:page], per_page: 2, load: true) do
query do
boolean do
must { string params[:name], default_operator: "AND" } if params[:name].present?
must { term :status, 'live' }
must { term :refno, params[:refno]} if params[:refno].present?
# must { term :tag, params[:tag]} if params[:tag].present? ## does not work either
must { term 'tags.name.exact', params[:tag]} if params[:tag].present?
end
end
facet "tags" do
terms 'tags.name.exact'
end
raise to_json
# raise to_curl
end
end
Я получаю 0 граней. Но если я переместу грани в фильтр, то есть ниже, я получу полные грани.
def self.search(params={})
tire.search(page: params[:page], per_page: 2, load: true) do
query do
boolean do
must { string params[:name], default_operator: "AND" } if params[:name].present?
must { term :status, 'live' }
must { term :refno, params[:refno]} if params[:refno].present?
end
end
filter :term, 'tags.name.exact' => params[:tag] if params[:tag].present?
facet "tags" do
terms 'tags.name.exact'
end
raise to_json
# raise to_curl
end
end
Хотя это нормально, это не нужно, но при щелчке по фасетному фильтру я хочу удалить недоступные теги из моего фасетного фильтра и обновить новое количество фасетов.
Если это поможет, вот JSON для запроса, который работает и не работает.
## No Factes
{
"query":{
"bool":{
"must":[
{
"query_string":{
"query":"England",
"default_operator":"AND"
}
},
{
"term":{
"status":"live"
}
},
{
"term":{
"tags.name.exact":[
"Pet Friendly"
]
}
}
]
}
},
"facets":{
"tags":{
"terms":{
"field":"tags.name.exact",
"size":10,
"all_terms":false
}
}
},
"size":2
}
## Facets working
{
"query":{
"bool":{
"must":[
{
"query_string":{
"query":"England",
"default_operator":"AND"
}
},
{
"term":{
"status":"live"
}
}
]
}
},
"facets":{
"tags":{
"terms":{
"field":"tags.name.exact",
"size":10,
"all_terms":false
}
}
},
"filter":{
"term":{
"tags.name.exact":[
"Pet Friendly"
]
}
},
"size":2
}
Очень надеюсь, что кто-то может посоветовать. Начинаю вырывать мне волосы на этом.
3 ответа
Я был на самом деле очень близко. Поскольку мои теги могут иметь несколько значений, мне нужно было использовать термины, а не термины, т.е.
def self.search(params={})
tire.search(page: params[:page], per_page: 2, load: true) do
query do
boolean do
must { string params[:name], default_operator: "AND" } if
must { term :status, 'live' }
must { term :refno, params[:refno]} if params[:refno].present?
must { terms 'tags.name.exact', params[:tag]} if params[:tag].present?
end
end
facet "tags" do
terms 'tags.name.exact'
end
# raise to_json
# raise to_curl
end
end
Спасибо за совет, хотя имотов, Хоанг.
Вы должны использовать фильтрованный запрос для поиска фасетов, чтобы получить точный результат:
query do
filtered do
query { <search keywords> }
filter <your filter> (pass in facet values)
end
end
<facet>
...
<facet>
Поисковый запрос обычно состоит из двух частей: запроса и фильтра. Если поисковый запрос содержит только часть запроса, фасеты рассчитываются на основе полного результата поиска. Другими словами, если результат поиска содержит 10 записей с тегом "Допускается размещение с домашними животными" и 5 записей с тегом "Запрещено размещение с домашними животными", ответный аспект будет содержать два аспекта: "Допускается размещение с домашними животными" и "Запрещено размещение с домашними животными". Теперь давайте предположим, что пользователь ограничивает результаты, выбирая тег "Pet Friendly". Если в запросную часть добавлено условие "Допускается размещение с домашними животными", результат поиска будет ограничен 10 записями с тегом "Допускается размещение с домашними животными", и будет возвращен только один фасет: "Допускается размещение с домашними животными". Однако, если в качестве фильтра добавлено предложение "Pet Friendly", результат поиска будет по-прежнему ограничен 10 записями, но будут возвращены два аспекта. Это происходит потому, что фасеты рассчитываются только на основе части запроса поискового запроса, а часть запроса не изменилась - она все равно дает результаты поиска с 15 записями с двумя разными фасетами.
Чтобы ответить на ваш вопрос, если запрос не возвращает результатов (например, пользователь выбрал оба тега "Допускается размещение с домашними животными" и "Не допускаются домашние животные"), то в результатах не будет фасетов, поэтому фасеты не возвращаются.