Order by an expression in Solr - solr

In SQL you can order by an expression like:
SELECT * FROM a
ORDER BY CASE WHEN a.Category = 20 THEN 1 ELSE 0 DESC
so records who have Category = 20 are on top.
Is this possible in Solr?

Solr doesn't have an if/then (at least not until 4.0), but it does have a map function and the ability to use function queries in your sort. You can probably use something like this in your sort to achieve what you're after:
?q=*&sort=map(category,20,20,case,0),score desc
(untested)
Here is a thread that talks about using map for an if statement.

I've accepted hross's answer, but it's also possible to do something like this in Solr 1.3 and up, using:
/select?q={!func}map(Category,20,20,1,0)&sort=score desc
The cool thing is that you can still sort on other fields, so:
&sort=score desc, name asc

If you are using the dismax request handler, then you can use boost queries in a similar fashion. http://wiki.apache.org/solr/DisMaxQParserPlugin#bq_.28Boost_Query.29 Note that this doesn't function exactly like the your SQL example, but you can achieve the same results with it.

Related

Solr: How to resort top documents from query?

I am running Solr 4.10.3 and trying to resort top 10 documents come from Solr. How can i do that? I am thinking of sub-query but don't know how to do that, needed help.
Example:
Suppose on query of "car" Solr return 250 documents on the basis of high score of relevancy. Now from 250 documents take top 10 documents and resort them on the basis of custom field.
i can't do that:
select?q=car&sort=score desc, pr desc
Because it will do sorting on entire 250 documents. So is there any solution?
I think you mean query reranking ? This is what is used when you want to:
use a first, more lightweight query to get a result based on the score
get a fair top x number of matches, like 2000 for example
use a heavier query to resort only those again, to get the final score
That is what you need to use if you want to do it in two steps, like you state. Now, I am not sure you need to use query reranking for your use case, maybe just boosting by that field, or sorting on a function should be enough for you.

How can I use Solr subquery similar to rdbms subqueries?

I need to run a query in Solr that contains another query as terms of the main query!
Something like this in the RDBMS SQL:
select name from movie
where movie.writer in (
select director from movie where producer = 'XXX'
)
Is there any way to do this is Solr?
Solved.
This is possible using "join" in Solr.
Following is the solution for my answered example:
fl=name&
q={!join from=writer to=director}+producer:XXX
Also a filter query can be added. This filter will affect the result of join and query.
Thanks to Ramzy.
you can try filter, something like this..
q=movie:name
fq=(writer:writer_name AND producer:Producer_name)
also the data that you put into a Solr index is flat or denormalized.
So take the suquery field values and put them in an AND part of the query to Solr.
q=(movie:name AND writer:Writer_name AND producer:Producer_name)

Solr query to return results ordered by 'find in set'

Here is the problem.
I have a solr query like this:
Example:
post_id: ( 31234, 56756, 24352, 78465, 23424 )
And i want to order them , as they are in the query.
Mysql equivalent to this is:
ORDER BY FIND_IN_SET(post_id, '31234, 56756, 24352, 78465, 23424')
I was looking on the Solr sort documentation, googling etc. but nothing.
Is it possible to order articles in Solr like this?
Thanks in advance.
You can only have that kind of Order if you boost your documents accordingly.
for e.g. q=post_id:31234^5 post_id:56756^4 post_id:24352^3 .....

solr sort,i want Specify a particular document at the first

solr sort,i want Specify a particular document at the first
for example:
Results :5,2,3,1
I want 2 at the first ,Other sorted in accordance with the rules
2,1,3,5
how to do this ?
I know of two ways you can try to tackle this using Solr.
The first is to use the QueryElevationComponent. This lets you define the top results at index time. As suggested in the documentation, this is good for placing sponsored results or popular documents at the top of the search results. The potential downside is that you have to be able to identify those documents at index time and not at query time.
The other approach is to boost the desired documents at query time using the bq parameter. To boost document 435, you would do something like this:
...&bq=id:435^10
Unfortunately, neither of these approaches give you absolute control over the order of the results.
The solution provided by Riking would certainly do the job if you don't mind processing the results after performing the search. Another approach you could consider is to add a field to your Solr schema that defines a display order or priority. You can then sort on that field to get the desired sort order.
If you are using Solr 3.1 or later, you can sort by a function query. The map function is useful for this.
sort=map(field_name,5,5,0) asc
In the above, field_name is the name of the field you want to sort by, 5 is the value you want to push to the front and 0 must be replaced with some number that you know is less than all other numbers.
Call the builtin sort() function, then shift the desired element to the front.
Pseudocode, in case you do not have a builtin method to shift it to the front:
tmp = desired;
int dIndex = array.indexOf(desired);
for(i=dIndex-1; i >= 0; i--)
{
array[i+1] = array[i]
}
In case you use standart query (not dismax) add "OR id:2^1000" to you query. Like this:
q=(text:lalala AND author:Bob) OR id:2^1000
that will place document with ID=2 at the top of results.

Google App Engine - keyword search + ordering on other properties

Say I have an entity that looks a bit like this:
class MyEntity(db.Model):
keywords = db.StringListProperty()
sortProp = db.FloatProperty()
I have a filter that does a keyword search by doing this:
query = MyEntity.all()\
.filter('keywords >=', unicode(kWord))\
.filter('keywords <', unicode(kWord) + u"\ufffd")\
.order('keywords')
Which works great. The issue I'm running into is that if I try to put an order on that using 'sortProp':
.order('sortProp')
ordering has no effect. I realize why - the documentation specifically says this is not possible and that sort order is ignored when using equality filters with a multi-valued property (from the Google docs):
One important caveat is queries with both an equality filter and a
sort order on a multi-valued property. In those queries, the sort
order is disregarded. For single-valued properties, this is a simple
optimization. Every result would have the same value for the property,
so the results do not need to be sorted further. However, multi-valued
properties may have additional values. Since the sort order is
disregarded, the query results may be returned in a different order
than if the sort order were applied. (Restoring the dropped sort order
would be expensive and require extra indices, and this use case is
rare, so the query planner leaves it off.)
My question is: does anyone know of a good workaround for this? Is there a better way to do a keyword search that circumvents this limitation? I'd really like to combine using keywords with ordering for other properties. The only solution I can think of is sorting the list after the query, but if I do that I lose the ability to offset into the query and I may not even get the results with the highest sort order if the data set is large.
Thanks for your tips!
Workaround 1:
Apply stemming algorithms for keywords then you won't need to do a comparison look up.
Workaround 2:
Store all unique keywords in separate entity group ("table"). From this group find keywords which match your criteria. Then do query with keywords IN [kw1, kw2, ...]. Make sure that the number of matching keywords is not too big, for example you can select only first 10.
Workaround 3:
Reorder list of items on application side
Workaround 4:
Use IndexTank for full-text search, or apply for "Trusted Tester Program" as mentioned by #proppy.
Instead of doing prefix matches, properly tokenize, stem and normalize your strings, and do equality comparisons on them.

Resources