全文搜索,过滤结果以获得最佳匹配

时间:2009-07-06 14:20:17

标签: .net sql sql-server full-text-search

我有3个表连接起来。餐馆,美食和美食类型。 餐厅可以出售许多美食(这是不好的措辞,但你有想法?)

所以我在餐厅设置了全文:名称,城市,邮政编码和烹饪类型:名称

我的主页上有一个搜索框,因为用户类型结果会被过滤到最佳匹配。

以下是一些例子: SearchText =“Royal D Ed” 现在餐厅有一排名为Royal Dynasty的地方,该镇是爱丁堡。 但我的最高结果是在某个地方,以D为名,以及D开头。这不是最好的匹配。

我会告诉你我的存储过程,原型所以派生的名字有点hackish。

ALTER PROCEDURE [dbo].[RestaurantsFullText]
    @searchText nvarchar(255) 
AS
SELECT 
    b.*, 
    COALESCE(akt2.[Rank],0) / 30 + 
    COALESCE(akt1.[Rank],0) / 30 + 
    COALESCE(akt.[Rank],0) / 30 + 
    COALESCE(bkt.[Rank],0)  as rankCount  
FROM 
    Restaurants b 
left JOIN Cuisines c on b.Id = c.RestaurantId 
left join CuisineType a 
ON c.CuisineId = a.id 

left JOIN 
containstable(Restaurants, Name, @searchText) bkt 
ON b.id = bkt.[Key] 

left JOIN containstable(CuisineType, Name, @searchText) akt 
ON a.id = akt.[Key]

left JOIN containstable(Restaurants, Postcode, @searchText) akt1 
ON b.id = akt1.[Key]

left JOIN containstable(Restaurants, citytown, @searchText) akt2 
ON b.id = akt2.[Key]

where 
    COALESCE(akt2.[Rank],0) / 30 + 
    COALESCE(akt1.[Rank],0) /30 + 
    COALESCE(akt.[Rank],0) / 30 + 
    COALESCE(bkt.[Rank],0)  > 5
ORDER BY 
    COALESCE(akt2.[Rank],0) / 30 + 
    COALESCE(akt1.[Rank],0) / 30 + 
    COALESCE(akt.[Rank],0) / 30 + 
    COALESCE(bkt.[Rank],0)   asc

我认为问题在于连接和排名的计算方式。

我想要它如果我通过“皇家王朝爱丁堡d”,那么皇家王朝仍然是最好的比赛。

由于它是一个过滤器,因此不应返回以d开头的其他城市的城镇匹配。

对于这方面的帮助,我会非常慷慨。

1 个答案:

答案 0 :(得分:2)

快速简便的第一步

我会解析字符串(如果使用SQL Server 2008,有inbuilt function删除噪声字,如果可能的话)并构建一个布尔类型的搜索字符串

“royal”和“d *”以及“ed *”,您可以在现有查询上运行。如果没有返回任何结果会将您的数据复合到单个视图或表格中,而不是所有单独的表格,因为可能在餐厅表格中找不到ED,因此被和忽略。

如果这不能让你足够接近。如果它是实时的,我会停下来查看人们正在进行的搜索,并且他们正在查看的数据会更紧密地用于改善这些结果。如果那是不可能的;我会在更改搜索之前构建该功能,因为在更改之前了解人们如何使用该软件是启动imo的最佳位置。可能存在改善事物的界面方式;例如最好通过向人们提供皇家王朝作为他们在搜索框中键入皇家d的选项来解决界面中的问题。

由于我不知道有多少人在您的应用中搜索餐馆名称,美食或位置,这是非常普遍的。根据您所看到的人们从您的日志中搜索的内容,我会以不同的方式处理事情。在这种情况下,我会更动态地构建我的搜索,而不是编码的单个传递查询(尽管每次搜索需要更多处理能力,因此您可能需要考虑这一点。)

考虑深入搜索数据或基于同义词库的分词器,它使用您的数据知识来确定结果的优先级。而不是将整个字符串抽入查找并尝试在您的菜单列表中找到Royal D,最好先在您的餐馆列表中找到它作为高匹配,然后将其从搜索字符串中删除;然后根据缩小的搜索字符串搜索位置/菜系中餐馆的所有匹配。这样,对菜肴和位置数据的搜索基于餐馆匹配(因此,当数据集减少时应该更快)并且您正在搜索更少的数据;可能是邮政编码字符串ED。

提供搜索结果的提示是一件好事;如果搜索非常快,用户通常会多次搜索以获得更好的结果,因此在结果屏幕上提供您是不是意味着爱丁堡将再次帮助您改善搜索。