none
sql全文检索多个列时,如何按照给定每个列不同的权值而排序呢? RRS feed

  • 问题

  • 我对一张表的多个列进行了全文索引(title,abstract,keyword等列),在使用关键字查询

    select * from [dbo].[table] where CONTAINS(*,'关键字')

    就可以得到我想要的结果,但是排序并不如预期。

    期望得到的排序类似于title字段如果出现关键字,一定排在最前面,title字段没有出现关键字,那么abstract不管出现多少个都要在后面。类似于这样的。

    如何才能实现给每个列分配权值,进行最终的排序?

    查资料只找到了给关键字增加权值,没有找到给字段增加权值的方法,能想到的方法如下,但是这样做总感觉是重复做了全文查询这件事,很别扭,有没有其他的方法?

    select * from [dbo].[table] where contains(*,'关键字')
    order by case when contains(Title,'关键字') then 1 else 2 end
    
    select *,rank=case when contains(Title,'关键字') then 1000 else 100 end from [dbo].[table] where contains(*,'关键字')
    order by rank desc


    我只愿面朝大海,春暖花开……


    • 已编辑 Kopelan 2014年7月15日 15:41 sql语句错误
    2014年7月15日 15:41

答案

  • Hi Elan-Asuka 我理解您的问题是希望使用SQL Server Full-Text Search全文检索功能,针对同一关键字,给表内的不同列分配不同的权重,并根据这些权重进行跨列排序。

    SQL Server Full-Text Search的权重WEIGHT是用来在单个列内为多个不同的关键字分配不同的权重,以达到在单个列内排序匹配结果的功能,并不支持跨列排序。

    具体使用时结合CONTAINSTABLE语句,它会返回一个RANK值用来表示匹配程度。

    参考http://msdn.microsoft.com/en-us/library/ms189760.aspx 可以看到weight的如上使用方法:

    USE AdventureWorks2012;
    GO
    
    SELECT FT_TBL.Name, KEY_TBL.RANK
        FROM Production.Product AS FT_TBL 
            INNER JOIN CONTAINSTABLE(Production.Product, Name, 
            'ISABOUT (frame WEIGHT (.8), 
            wheel WEIGHT (.4), tire WEIGHT (.2) )' ) AS KEY_TBL
                ON FT_TBL.ProductID = KEY_TBL.[KEY]
    ORDER BY KEY_TBL.RANK DESC;
    GO

    这段代码在Product表的Name列上为多个匹配关键字赋了不同的权重,其中'frame'为0.8,'whee'为0.4,'tire'为0.2。

    如果需要实现您提到的跨列排序算法,仍旧需要结合其他的SQL排序等语句来实现所需的功能,如您提到的:

    select * from [dbo].[table] where contains(*,'关键字')
    order by case when contains(Title,'关键字') then 1 else 2 end

    关于SQL Server如何为CONTAINSTABLE返回RANK值的,请参考下面的文档:

    http://msdn.microsoft.com/en-us/library/ms142524(v=sql.105).aspx   How Search Query Results Are Ranked ( Full-Text Search)


    希望能有所帮助。


    • 已编辑 SQL Team - MSFT 2014年7月18日 2:36 Add more information
    • 已标记为答案 Kopelan 2014年7月22日 14:56
    2014年7月18日 2:31

全部回复

  • Hi Elan-Asuka 我理解您的问题是希望使用SQL Server Full-Text Search全文检索功能,针对同一关键字,给表内的不同列分配不同的权重,并根据这些权重进行跨列排序。

    SQL Server Full-Text Search的权重WEIGHT是用来在单个列内为多个不同的关键字分配不同的权重,以达到在单个列内排序匹配结果的功能,并不支持跨列排序。

    具体使用时结合CONTAINSTABLE语句,它会返回一个RANK值用来表示匹配程度。

    参考http://msdn.microsoft.com/en-us/library/ms189760.aspx 可以看到weight的如上使用方法:

    USE AdventureWorks2012;
    GO
    
    SELECT FT_TBL.Name, KEY_TBL.RANK
        FROM Production.Product AS FT_TBL 
            INNER JOIN CONTAINSTABLE(Production.Product, Name, 
            'ISABOUT (frame WEIGHT (.8), 
            wheel WEIGHT (.4), tire WEIGHT (.2) )' ) AS KEY_TBL
                ON FT_TBL.ProductID = KEY_TBL.[KEY]
    ORDER BY KEY_TBL.RANK DESC;
    GO

    这段代码在Product表的Name列上为多个匹配关键字赋了不同的权重,其中'frame'为0.8,'whee'为0.4,'tire'为0.2。

    如果需要实现您提到的跨列排序算法,仍旧需要结合其他的SQL排序等语句来实现所需的功能,如您提到的:

    select * from [dbo].[table] where contains(*,'关键字')
    order by case when contains(Title,'关键字') then 1 else 2 end

    关于SQL Server如何为CONTAINSTABLE返回RANK值的,请参考下面的文档:

    http://msdn.microsoft.com/en-us/library/ms142524(v=sql.105).aspx   How Search Query Results Are Ranked ( Full-Text Search)


    希望能有所帮助。


    • 已编辑 SQL Team - MSFT 2014年7月18日 2:36 Add more information
    • 已标记为答案 Kopelan 2014年7月22日 14:56
    2014年7月18日 2:31
  • 感谢解答~暂时先这么解决,等之后有空了再看看有没有其他突破口…

    我只愿面朝大海,春暖花开……

    2014年7月22日 14:57