Question

I have a list of users in a table and when performing a search on table, I want the usernames that begin with search key to appear on top of the list, followed by users who have the search key in their username.

For example, consider the list of usernames:

rene
irene
adler
leroy
Argog
harry
evan

I am providing "suggestions" as the user types in a search box when they are trying to search for other users. If the users types va into the search box, more often than not they will be looking for the user vain, but because I'm sorting the users by username, ascending order, evan is always on top. What I'd want is to order like so:

searching for va

vain
evan

searching for re

rene
Irene

searching for ar

Argog
harry

Of course, if they enter one more character it will be narrowed down further.

Thinking of it, this is what I want to do - put the username that starts with search key on top (if multiple usernames start with the search key, sort them alphabetically). Then, if the required number of usernames isn't complete, append the other usernames that contain search key in them, alphabetically.

I'm paginating the results in sql itself - and I'm using nhibernate queryover to perform the task. By if the required number of usernames isn't complete, I mean if the page size is 10 and I have only 7 usernames, append other usernames that contain searchkey in them.

I can't currently see a way to do all this in one query.. do I have to split the query into two parts and contact the db twice to get this done? or is there a way I can sort with position of the string?

Any hints about how to efficiently do this would be very helpful. - I can't even think of the query that would do this in plain sql..

thanks.


Solution

The accepted answer pushed me in the right direction and this is what finally worked for me:

.OrderBy(Projections.Conditional(
    Restrictions.Where(r => r.Username.IsLike(searchKey + "%")),
    Projections.Constant(0),
    Projections.Constant(1))).Asc();
Was it helpful?

Solution

In plain SQL you could craft an ORDER BY clause such as:

ORDER BY CASE WHEN field LIKE 'VA%' THEN 0
              WHEN field LIKE '%VA%' THEN 1
              ELSE 2
         END

Of course you can use variables/field names instead.

Not sure as to the rest of your question.

OTHER TIPS

QueryOver based on Goat_CO's idea:

session.QueryOver<YourClass>()
       .OrderBy(
           Projections.Conditional(
               Restrictions.Like(Projections.Property<YourClass>(x => x.Pro),
                                 searchString,
                                 MatchMode.Anywhere),
               Projections.Constant(0),
               Projections.Constant(1)))
       .Asc;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top