【问题标题】:full text search, filter results for best match全文搜索,过滤结果以获得最佳匹配
【发布时间】:2009-07-06 14:20:17
【问题描述】:

我有 3 个链接在一起的表。餐厅、美食和美食类型。 一家餐厅可以出售多种美食(这是不好的措辞,但你明白吗?)

所以我在 Restaurant:Name、CityTown、Postcode 和 CuisineType:Name 上设置了全文

我的主页上有一个搜索框,当用户键入时,结果会被过滤为最佳匹配。

这里有几个例子: SearchText = "皇家版" 现在餐厅里有一排叫皇家王朝的地方,小镇就是爱丁堡。 但我返回的最佳结果是某个城镇以 D 和名称开头的地方。这不是最好的匹配。

我将向您展示我的存储过程、原型,因此派生的名称有点骇人听闻。

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 开头的其他城市的城镇匹配。

我会非常感激这方面的帮助。

【问题讨论】:

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


    【解决方案1】:

    快速简单的第一步

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

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

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

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

    考虑对数据进行深度搜索,或者考虑基于词库的分词器,它使用您的一些数据知识来确定结果的优先级。与其将整个字符串泵入查找并尝试在您的美食列表中找到 Royal D,不如先在您的餐厅列表中找到它作为高度匹配,然后将其从您的搜索字符串中删除;然后根据减少的搜索字符串搜索位置/美食餐厅的所有匹配项。这样,对美食和位置数据的搜索基于餐厅匹配(因此随着数据集的减少应该更快),并且您正在使用更少的数据进行搜索;可能是邮政编码字符串 ED。

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

    【讨论】:

    • 谢谢,我已经稍微更新了设计(我不是设计师,所以一次只做一点点;))我想接下来的几天我需要花在搜索和按邮政编码过滤都在我的脑海里。我一点也不擅长 SQL
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-02-12
    • 1970-01-01
    • 2011-08-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多