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: {
:"*" => {}
}
}
}
Related
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'}}
}]
}
}
}}
]
}
}
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"
}
}
})
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"
}
}
}
I am trying to get the top 5 products sold, ordered by revenue using elasticsearch in Rails.
Here is my query:
query = {
bool: {
filter: {
bool: {
must: [
{ term: { store_id: store.id } } # Limiting the products by store
]
}
}
}
}
aggs = {
by_revenue: {
terms: {
size: 5,
order: {revenue: "desc"}
},
aggs: {
revenue: {
max: {
script: "doc['price_as_float'].value * doc['quantity'].value"
}
}
}
}
}
response = OrderItem.search(query: query, aggs: aggs, size: 0)
I get the error could not find the appropriate value context to perform aggregation [by_revenue]
Thanks!
You need to aggregate orders on product reference, then summing the prices * quantity to get the revenues from one product with a nested sum aggregation, not max:
aggs: {
products: {
terms: {
field: "product_ref",
order: { revenues: "desc" },
},
aggs: {
revenues: {
sum: { script: "doc['price_as_float'].value * doc['quantity'].value" }
}
}
}
}
Don't use the size option in the terms aggregation, because you're not sure all the orders for your top products are located in the same shard; you should get them from the response instead.
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