开发者

How to order query results by search term first, and then alphabetically?

开发者 https://www.devze.com 2023-03-10 18:30 出处:网络
I\'m using NHibernate to do a search on item name. I\'m getting a paged list of items back from the database, and I\'m ordering it by item name ascending.

I'm using NHibernate to do a search on item name. I'm getting a paged list of items back from the database, and I'm ordering it by item name ascending.

So, if I search for 'term', I get back a page of results that contains 'term' anywhere in the result, and the page is ordered alphabetically.

For example, the results might look like this

a term
d term
g term
j term
p term
s term
term 1
term 2
v term    
z term

Technically this list is correct, because it's ordered alphabetically.

However, technically correct is not good enough for the client. They want the list to be ordered first by the relevance of the term being searched for, and then alphabetically.

So the result would become

term 1
term 2
a term
d term
g term
j term
p term
s term
v term    
z term

I don't know how to constru开发者_StackOverflow社区ct this query, or if its even possible. If this could be done in the application it would be much easier, but because of the paging, this has to be done on the database. This is what complicates things. Could somebody please point me in the right direction here?


I've never seen anything that sophisticated in SQL or Linq to search by 'relevancy'.

If this was my problem I would look to create a customised helper class which implements IComparer. You could then create any number of nuanced conditions in code. Of course this isnt done server side.

I wonder if there is a thrid party .net library, that could specifically quantify relevancy.


If it's possible to write a function that returns an integer based on the relevancy, you could do

SELECT MyField
FROM MyTable
WHERE MyField like '%term%'
ORDER BY GetRelevance(MyField, SearchTerm) DESC

Your function wouldn't have to be very complicated. It could just look to see if the Field Starts with the SearchTerm and return 2 and if it doesn't return 1. Then you could expand it if you have more criteria of relevancy.

Or if by relevancy you mean it starts with the search term, you could also split your DB query into two and union them together.

i.e.

SELECT MyField
FROM MyTable
WHERE MyField LIKE 'term%' 
ORDER by MyField

union
SELECT MyField
FROM MyTable
WHERE MyField LIKE '%term%' AND NOT LIKE 'term%'
ORDER BY MyField

It's not going to be good for your performance though.


Thanks to Ray's suggestion, I implement the following:

CREATE FUNCTION [dbo].[fnGetRelevance] 
(   
    @fieldName nvarchar(50),
    @searchTerm nvarchar(50)
)

RETURNS  int
AS
BEGIN
    if (@fieldName like @searchTerm + '%') -- starts with
    begin       
        return 0
    end
    else if ((@fieldName like '%' + @searchTerm + '%') and (@fieldName not like @searchTerm + '%')) -- contains, but doesn't start with 
    begin       
        return 1
    end

    return 1
END

GO

This resulted in the following performance impact for 1 of the larger queries:

How to order query results by search term first, and then alphabetically?

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号