Im using SearchKick which is great, Im migrating from a really bad search implementation and the product team didn't give me much trust as such before migrating to SearchKick and doing an overhaul to our search, they made me add hardcoded query results, so they can say for this search input I want this product to come up first. right now Im taking the query results that answer a certain the requested query from the db and add them at the top ( I don't care if you want the result at position 48, if there are 4 hard coded results it will be the 4th). although if possible it would be nice to do put them in the middle.
What is the cleanest way to do it with SearchKick, so that the querying will happen inside elastic ( index the hardcoded results in the product to do so )
I have 2 models Product and QueryResult, QueryResult contains a product, a query string & a wanted_rank
in my Product model I do have a method to get search results that looks something like this:
def get_search_results(query_string)
# get search results from elastic using searchkick
search_results = Product.search(query_string)
# get hardcoded results matching this query
hardcoded_results = QueryResults.where(query: query).order(:wanted_rank).map(&:product)
# remove hardcoded results from search_results
search_results = search_results - hardcoded_results
# return results where hardcoded results are first
hardcoded_results + search_results
end
In the end I want all the search logic to happen over elastic including inserting hardcoded search results
So after some very helpful comments and more search I found a solution. first of all my first mistake was to try to fix it using boosts instead of order, to do so we index all QueryResults of a specific product under a field called called query_results. for a product x with query results:
{
query: 'foo',
wanted_rank: 1,
},
{
query: 'bar',
wanted_rank: 2,
}
I will index:
{
name: 'x',
query_results: {
'foo': 1,
'bar': 2
}
}
than when searching, given a attribute named query, I will do as follow:
Product.search(
query,
order: [
{ "query_results.#{query}": { unmapped_type: :long },
{ _score: :desc }
]
)
2 important things to notice:
also I index the queries under another field and do a search over it with low weight to make sure that the product will come up for that query.