Add Filter To ElasticSearch Query - ruby-on-rails

I'm trying to create a query where the user can search for ES documents where the brand field is equal to some string. Here is the query I currently have that works but has no filtering. I'm using elasticsearch-rails with Ruby on Rails.
#products = Product.search(
query:{
function_score:{
query: {
multi_match: {
fields: ['brand^5', '_all'],
query: "#{query}",
fuzziness: "AUTO"
}
},
field_value_factor:{
field: "popularity",
modifier: "log1p"
}
}
}).page(page).per(25)
I've statically assigned a brand name to the filter for testing purposes. In this case the user should be seeing results for their search keyword where the brand name is "NordicTrack".
query:{
function_score:{
query: {
multi_match: {
fields: ['brand^5', '_all'],
query: "#{query}",
fuzziness: "AUTO"
}
},
filter: {
term: {"brand":"NordicTrack"}
},
field_value_factor:{
field: "popularity",
modifier: "log1p"
}
}
}
).page(page).per(25)
This query gives me the following error:
[400] {"error":{"root_cause":[{"type":"parsing_exception","reason":"no [query] registered for [filter]","line":1,"col":139}],"type":"parsing_exception","reason":"no [query] registered for [filter]","line":1,"col":139},"status":400}
I'm not sure why this isn't working. Any help would be appreciated!

I'm not sure about how Elasticsearch-rails with Ruby on Rails parses Query. But I tried below query in Kibana :
GET test/testt/_search
{
"query": {
"filter": {
"term": {
"brand": "NordicTrack"
}
}
}
}
which is somewhat similar to your part of the query which is giving you the error and I too got that same error.
But when I wrap the term query with bool query then it returns desired results. Query :
GET test/_search
{
"query": {
"bool": {
"filter": {
"term": {
"brand": "NordicTrack"
}
}
}
}
}
Give it a Shot.

Try using a filtered query like this:
query: {
function_score: {
query: {
filtered: {
query: {
multi_match: {
fields: ['brand^5', '_all'],
query: "#{query}",
fuzziness: "AUTO"
}
},
filter: {
term: {
brand: "NordicTrack"
}
}
}
},
field_value_factor:{
field: "popularity",
modifier: "log1p"
}
}
}

Related

Elastic Search with multiple result

I have this query below but it return 1 result only, now i want it to return multiple one and can be paginate (with or without Kaminari). I'm new to elasticsearch so please help
query: {
bool: {
should: [
{nested: {
path: 'item_info',
query: {
bool: {
should: [{
match: {'item_info.name': {query: params[:item_request][:key_word], fuzziness: 'AUTO'}}
},
{
match: {'item_info.sku': {query: params[:item_request][:key_word], fuzziness: 'AUTO'}}
},]
}
}
}},
{nested: {
path: 'catalog',
query: {
bool: {
should: [{
match: {'catalog.name': {query: params[:item_request][:key_word], fuzziness: 'AUTO'}}
}]
}
}
}},
{nested: {
path: 'companies',
query: {
bool: {
should: [{
match: {'companies.name': {query: params[:item_request][:key_word], fuzziness: 'AUTO'}}
}]
}
}
}}
]
}
}

Elasticsearch field value factor with multi matching?

I'm using this to search my outfits:
def self.search(query, purchasedlow, purchasedhigh)
__elasticsearch__.search(
{
query: {
function_score: {
query: {
bool: {
filter: [
{
multi_match: {
query: query,
fields: ['name','description','material']
}
},
{
range: {
purchased: { lte: purchasedhigh.to_i, gte: purchasedlow.to_i},
},
}
]
}
}
}
}
}
)
end
But I don't know how to add this code:
field_value_factor: {
field: "likes",
factor: "100"
}
I know that I'm supposed to put it after the function score, so that the calculated score is then multiplied by the amount of likes to make the final score, but when I put the code after the function_score, I get the following error:
[400] {"error":{"root_cause":[{"type":"parsing_exception","reason":"[function_score] malformed query, expected [END_OBJECT] but found [FIELD_NAME]","line":1,"col":232}],"type":"parsing_exception","reason":"[function_score] malformed query, expected [END_OBJECT] but found [FIELD_NAME]","line":1,"col":232},"status":400}
Where do I need to put the field value factor so that it works correctly?
I used field_value_factor in one of my queries like this:
#products = Product.search(
query:{
function_score:{
query:{
bool:{
must:{
multi_match:{
fields: ['brand^5', '_all'],
query: "#{query}",
fuzziness: "AUTO"
}
},
filter:{
bool:{
must:[
{term: {"brand":"NordicTrack"}},
{term: {"product_type":"Treadmill"}}
]
}
}
}
},
field_value_factor:{
field: "popularity",
modifier: "log1p"
}
}
})

Filtered search with Authorization for Elasticsearch

I'm trying to do a search where I look for "test" in any field while filtering for a specific client in the client_id field. Can't seem to figure this one out. This is how fat I got (but it's not working):
{
query: {
filtered: {
query: "test",
filter: {
term: {client_id: #client.id}
}
}
}
}
This is the right syntax
{
"query": {
"filtered": {
"query": {
"match": {
"_all": "test"
}
},
"filter": {
"term": {
"client_id": #client.id
}
}
}
}
}
From ES Docs: The _all field allows you to search for values in documents without knowing which field contains the value

Elasticsearch-rails, highlights query

I'm trying to get highlights from the Elasticsearch-rails gem, but I can't get it to work.
My search method:
query = {
query: {
filtered: {
query: {
match: {
_all: params[:q]
}
},
filter: {
term: {
active: true
}
}
},
},
highlight: {
fields: {
_all: {fragment_size: 150, number_of_fragments: 3}
}
}
}
#results = Elasticsearch::Model.search(query, [Market, Component]).results
When I map my results in the view to check if there are any highlights, I get an array of false:
= #results.map(&:highlight?)
I read through the Elasticsearch docs here: https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-highlighting.html and the gem's documentation here: https://github.com/elastic/elasticsearch-rails/tree/master/elasticsearch-model and my query seems to be correct. Not sure how to proceed.
Apparently, the solution was to use "*" instead of "_all":
query = {
query: {
filtered: {
query: {
match: {
_all: params[:q]
}
},
filter: {
term: {
active: true
}
}
},
},
highlight: {
tags_schema: "styled",
fields: {
:"*" => {}
}
}
}

Tire multi search with RAW Json

I'd like make a multi query on Elasticsearch through Tire but with raw JSON
I can to a single request like this
#search = Tire.search('questions', query: {
function_score: {
query: {
bool: {
must: [
{
terms: {
interests: [2943,5106,3540,1443,3639]
}
}
]
}
},
random_score: {}
}
})
But for multiple I can't.
I'd like somthing like this, but it's not correct for now...
#search = Tire.multi_search 'questions' do
search :level2 do
query: {
function_score: {
query: {
bool: {
must: [{
terms: {
interests: [5090,2938,3062]
}}]
}
},
random_score: {}
}
}
end
end
Do you now how I could do to make it work?
Thank you
I found the solution.
Actually, in my case Search method is requiring :payload key in options params
#search = Tire.multi_search 'questions' do
search( :level1, :payload => {
query: {
function_score: {
query: {
bool: {
must: [
{
terms: {
interests: [2943,5106,3540,1443,3639]
}
},{
term: {
difficulty: 1
}
}
]
}
},
random_score: {}
}
}})
search( :level2, :payload => {
query: {
function_score: {
query: {
bool: {
must: [
{
terms: {
interests: [5160,2938,3062]
}
},{
term: {
difficulty: 2
}
}
]
}
},
random_score: {}
}
}})
end

Resources