我正在使用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
我不知道如何构造此查询,或者它是否可能。如果这可以在应用程序中完成,那将更容易,但由于分页,这必须在数据库上完成。这使事情复杂化。有人可以指点我在正确的方向吗?
答案 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
这导致以下一个较大查询的性能影响如下: