Solr - Relevancy based on a range + outside the range - solr

In my query, I want to search for a price based on a range of values (ex. $500 - $1000) and return a fuzzy result set.
I can boost these values by doing price:[500 TO 1000]^10, but then it doesn't score $499 as any more relevant than $200.
I can create a boost function like: recip(abs(sub(price,750)),1,1000,1000)^10, but this scores 501 as more relevant than 500.
Is there any way to have one boost function for $500-$1000 and another boost function for values outside that range?
Thanks,
Drew
Edited for typo in the function

recip(abs(sub(price,750)),1,1000,1000)^10
Use the mid-point of your range instead of the lower bound.
Edit: To answer the updated question:
Take a look at the map function here - you can map all prices between 500 and 1000 to 750 and then use that for boosting. Something like:
recip(abs(sub(map(price,500,1000,750),750)),1,1000,1000)^10
This should score 600 and 700 the same but it will score 400 higher than 300.

Related

Solr field for storing range

Is there a solr field type that would work well storing a range of two values?
For example, I'm trying to store a min and max cost for each document i.e. $0 to $100, or $50 to $100
I'd then want to be able to query a single value to see if it falls in the range. i.e. which documents' range allows $25?
I realize a workaround would be to store min and max separately, but wondering if any native fields support this to simplify querying?
There is no field which stores data range as integer and providing results according to that data. You can have a look at Solr field here
As you said you can keep min and max as separate fields and it will not make your query complicated. You only need to have value < field_max && value > field_min. this query in your solr query.

Solr Boost-Function on Sales

I am using Apache Solr 8 with products as documents. Each document includes sales within the last X days that I want to boost, as well as a title and other fields.
Say productA has been sold 5 times, I want to boost it with score+10; a productB has been sold 50 times, I want to boost the score by 30.
I tried to use a boostFunction that looks like (edismax query parser)
q=Coffee&qf=title&bf=if(lt(sales,5),10,if(lt(sales,50),30))
Solr now returns documents that have nothing to do with my "Coffee"-Query but just match the boostfunction. There are even results with score "0".
E.g.
Rank;Score;Sales;Title
1;58.53;55;Coffee big
2;38.11;50;Coffee
3;30;55;Tea
Any idea to get rid of those "only boost function"-matches?
Found the answer!
My Query-Fields actually included boostings like
&qf=title^2 longDescription^0 whatever^0...
Instead of excluding the results found in those 0-boosted fields, solr adds them and matches with - well score 0.
When I remove the 0-boostings, everything works as intended.

Applying a range filter only for a particular field with specific value in SOLR

I have data indexed into solr as with fields like :-
name:Apples weight:5kg
name:Grapes weight:2kg
name:papaya weight:7kg
name:Apples weight:3kg
name:Grapes weight:3kg
I want my results to be shown in such a way that all my results except Apples comes as usual results and after that the results for apples are shown at the end that too with weight range of 4-8 kg only.
i.e the results for apples are shown at the end that too with a particular weight range.
First you'll have to limit the documents you want to your criteria - i.e. you want all documents, except for those that are apples and outside of 4-8kg (this assumes that your weight field is an integer - if it isn't - make it an integer field so that you can do proper range searches):
q=(*:* NOT name:Apples) OR (name:Apples AND weight[4 TO 8])
Then you can apply a negative boost to Apples (which you do by boosting everything that doesn't match by a large factor):
bq=(*:* -name:Apples)^1000

How to apply boosting in solr

I am new to solr, please help me in boosting fields.
I have a query like this,
q=name:test* OR description:test*
i want to apply boosting/weight age for name its 500 and for description its 50.
for example:
lets consider "test" term is appearing for 1 time in name field in one record and 20 times in description field its from another record, then boosting calculation should happen like below.
for name: 1 X 500 = 500
for Description: 20 X 50 = 1000.
as result the records with high boosting value should come at top.
so based on above calculation the record which having description field with 20 matches should come on top after that record with 1 match in name field.
If any one have solution for this, please provide
Thanks in advance.
You can boost a field at index time with the boost attribute, or you can apply a boost in the query, such as q=name:test*^50 OR description:test* (and there are some more advanced features here as well).
I bears noting though, Lucene, by default, applies a length normalization that effectively weighs matches on shorter fields more heavily than longer fields. It sounds a bit like that is what you are trying to recreate.
If you need the scoring calculation to be as simple as what you have provided, you would need to write your own Similarity class, I believe.

How can accent can be more accurate with bf and query with solr

i work with solr, i can't fix my problem of result's accuracy (q vs bf taking into account accents)
i have a solr index with 2 fields indexed (this is simplified):
town, population
Félines, 100
Ferrand, 10000
when i query: q=Fé&qf=town town_ascii&bf=population^2&defType=dismax
I'd like this order on my results : Félines > Ferrand.
When i query: q=Fe&qf=town town_ascii&bf=population^2&defType=dismax I'd like this order on my results : Ferrand > Félines
The trouble is that Ferrand beats every time Félines because its population is bigger, how can i solve that? I didn't find how to use the score of the query and use it in bf to balance population
You didn't post your schema.xml but I suppose you're using the ASCIIFoldingFilterFactory for the town_ascii field. It means that if you're indexing the word Félines the following are the indexed terms:
town: Félines
town_ascii: Felines
Therefore, you're saying that a match for the town field is more important than a match for town_ascii. You should change the qf parameter to something like qf=town^3 town_ascii to give more weight to the town field. Then you can adjust the weight depending on what is the desired weight for town compared to population.

Resources