如何首先按搜索词排序查询结果,然后按字母顺序排序?

时间:2011-06-07 10:05:54

标签: c# nhibernate

我正在使用NHibernate对项目名称进行搜索。我从数据库中获取了一个分页项目列表,我按项目名称升序排序。

因此,如果我搜索“term”,我会在结果中的任何位置返回包含“term”的结果页面,并按字母顺序排序页面。

例如,结果可能如下所示

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

从技术上讲,这个列表是正确的,因为它是按字母顺序排列的。

但是,技术上的正确对客户来说还不够好。他们希望首先根据搜索词的相关性来排序列表,然后按字母顺序排序。

所以结果会变成

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

我不知道如何构造此查询,或者它是否可能。如果这可以在应用程序中完成,那将更容易,但由于分页,这必须在数据库上完成。这使事情复杂化。有人可以指点我在正确的方向吗?

3 个答案:

答案 0 :(得分:2)

我从来没有在SQL或Linq中看到任何复杂的东西来搜索“相关性”。

如果这是我的问题,我会寻找创建一个实现IComparer的自定义助手类。然后,您可以在代码中创建任意数量的细微差别条件。当然这不是服务器端。

我想知道是否有一个第三方.net库,它可以专门量化相关性。

答案 1 :(得分:1)

如果可以编写一个基于相关性返回整数的函数,则可以执行

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

你的功能不一定非常复杂。它可以查看Field Starts是否与SearchTerm一起开始并返回2,如果它没有返回1.那么如果你有更多的相关性标准,你可以扩展它。

或者,如果相关性是指从搜索词开始,您还可以将数据库查询拆分为两个并将它们合并在一起。

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

但这对你的表现并不好。

答案 2 :(得分:1)

感谢Ray的建议,我实现了以下内容:

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

这导致以下一个较大查询的性能影响如下:

enter image description here