Elastic Search with multiple result - ruby-on-rails

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'}}
}]
}
}
}}
]
}
}

Related

Elasticsearch search query issue

I am not being able to get the hits from the elasticsearch server. My code-
client = Elasticsearch::Client.new log: true
client.indices.refresh index: 'property_index'
# search_results = client.search(body: { query: { multi_match: { query: search_params, fields: ['street_address', 'suburb'] } } })
match_query = [
{ match: { status: 'Active'} }
]
match_query << { match: { is_published: true} }
match_query << { match: { paid: true} }
match_query << { match: { suburb: params[:suburb].to_s} } if !params[:suburb].blank?
match_query << { match: { advertise_type: params[:advertise_type].to_s} } if !params[:advertise_type].blank?
match_query << { match: { state: params[:state].to_s} } if !params[:state].blank?
match_query << { match: { postal_code: params[:postal_code]} } if !params[:postal_code].blank?
response = client.search(body: {
query: { bool: { must: match_query }},
sort: [
{ updated_at: { order: "desc" }}
]
}, from: params[:offset], size: params[:limit])
all_records = client.search(body: {
query: { bool: { must: match_query }},
sort: [
{ updated_at: { order: "desc" }}
]
})
This is the response output that i am getting-
GET http://localhost:9200/_search?from=0&size=10 [status:200, request:0.010s, query:0.003s]
2018-11-20 18:25:34 +0530: > {"query":{"bool":{"must":[{"match":{"status":"Active"}},{"match":{"is_published":true}},{"match":{"paid":true}},{"match":{"advertise_type":"Sell"}}]}},"sort":[{"updated_at":{"order":"desc"}}]}
2018-11-20 18:25:34 +0530: < {"took":3,"timed_out":false,"_shards":{"total":1,"successful":1,"failed":0},"hits":{"total":0,"max_score":null,"hits":[]}}
2018-11-20 18:25:34 +0530: GET http://localhost:9200/_search [status:200, request:0.008s, query:0.002s]
2018-11-20 18:25:34 +0530: > {"query":{"bool":{"must":[{"match":{"status":"Active"}},{"match":{"is_published":true}},{"match":{"paid":true}},{"match":{"advertise_type":"Sell"}}]}},"sort":[{"updated_at":{"order":"desc"}}]}
2018-11-20 18:25:34 +0530: < {"took":2,"timed_out":false,"_shards":{"total":1,"successful":1,"failed":0},"hits":{"total":0,"max_score":null,"hits":[]}}
It's kind of difficult to tell what's wrong if we do not know about the structure or what you're trying to achieve with the query.
The information log says the following:
timed_out:false
Shards:
total:1
successful: 1
failed:0
Hits:
total: 0
Which means, that the query was successful, and the server encountered no errors. It just did not find any matching documents to your query.
I'd recommend using a proper tool to first try your queries, for an example Kibanas' search profiler (https://www.elastic.co/guide/en/kibana/current/xpack-profiler.html).
This shows you information about your query, once you find your query suitable, you can integrate it into your code.

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

Add Filter To ElasticSearch Query

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"
}
}
}

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