【问题标题】:SQL Server Full Text SearchingSQL Server 全文搜索
【发布时间】:2010-09-06 05:36:33
【问题描述】:

我目前正在开发一个应用程序,其中我们有一个 SQL-Server 数据库,我需要进行全文搜索,以便我们搜索人名。

目前,用户可以在搜索 3 个不同 varchar cols 的名称字段中输入 a。名、姓、中间名

假设我有 3 行包含以下信息。

1 - 菲利普 - J - 弗莱

2 - 艾米 - NULL - 黄

3 - Leo - NULL - Wong

如果用户输入诸如“Fry”之类的名称,它将返回第 1 行。但是,如果他们输入 Phillip Fry、Fr 或 Phil,他们将一无所获。我不明白为什么要这样做。如果他们搜索 Wong,他们会得到第 2 行和第 3 行,如果他们搜索 Amy Wong,他们会再次一无所获。

当前查询正在使用 CONTAINSTABLE,但我已将其切换为 FREETEXTTABLE、CONTAINS 和 FREETEXT,结果没有任何明显差异。首选表格方法,因为它们返回相同的结果但有排名。

这是查询。

....
@Name nvarchar(100),
....
--""s added to prevent crash if searching on more then one word.
DECLARE @SearchString varchar(100)
SET @SearchString = '"'+@Name+'"'
SELECT Per.Lastname, Per.Firstname, Per.MiddleName
FROM Person as Per
INNER JOIN CONTAINSTABLE(Person, (LastName, Firstname, MiddleName), @SearchString) 
AS KEYTBL
ON Per.Person_ID = KEYTBL.[KEY]
WHERE KEY_TBL.RANK > 2
ORDER BY KEYTBL.RANK DESC;  
....

任何想法...?为什么这个全文搜索不能正常工作?

【问题讨论】:

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


    【解决方案1】:

    FreeTextTable 应该可以工作。

    INNER JOIN FREETEXTTABLE(Person, (LastName, Firstname, MiddleName), @SearchString) 
    

    @SearchString 应该包含像“Phillip Fry”这样的值(一个长字符串,包含所有用空格分隔的查找字符串)。

    如果您想搜索 Fr 或 Phil,您应该使用星号:Phil* 和 Fr*

    “Phil”正在寻找“Phil”这个词。 'Phil*' 正在寻找以 'Phil' 开头的每个单词

    【讨论】:

      【解决方案2】:

      如果您只是搜索人们的姓名,最好不要使用全文索引。当您有大文本字段时,全文索引很有意义,但如果您主要处理每个字段一个单词,我不确定您会从全文索引中获得多少额外收益。在搜索新记录之前等待全文索引自行重新索引可能是众多问题之一。

      您可以进行如下查询。在空格上拆分您的搜索字符串,并创建一个搜索词列表。

      选择名字、中间名、姓氏 从人 在哪里 名字如@searchterm1 + '%' 或 MiddleName 如 @searchterm1 + '%' 或姓氏,如 @searchterm1 + '%' 或名字如@searchterm2 + '%' 等等....

      【讨论】:

        【解决方案3】:

        另一种方法可能是将搜索从各个字段中抽象出来。

        换句话说,在您的数据上创建一个视图,它将所有拆分字段(如名字姓氏)转换为连接字段,即全名

        然后搜索视图。这可能会使搜索查询更简单。

        【讨论】:

          【解决方案4】:

          感谢大家的回复,我终于可以让它工作了。 Biri 和 Kibbee 的部分答案。我需要在字符串中添加 * 并将其分解为空格才能工作。所以最后我得到了

          ....
          @Name nvarchar(100),
          ....
          --""s added to prevent crash if searching on more then one word.
          DECLARE @SearchString varchar(100)
          
          --Added this line
          SET @SearchString = REPLACE(@Name, ' ', '*" OR "*')
          SET @SearchString = '"*'+@SearchString+'*"'
          
          SELECT Per.Lastname, Per.Firstname, Per.MiddleName
          FROM Person as Per
          INNER JOIN CONTAINSTABLE(Person, (LastName, Firstname, MiddleName), @SearchString) 
          AS KEYTBL
          ON Per.Person_ID = KEYTBL.[KEY]
          WHERE KEY_TBL.RANK > 2
          ORDER BY KEYTBL.RANK DESC;  
          ....
          

          搜索的字段更多,我只是简化了问题,对此感到抱歉,我认为这不会影响答案。它实际上搜索包含昵称的 csv 列和注释列的列。

          感谢您的帮助。

          【讨论】:

          • 请注意,星号作为通配符仅在搜索词的结尾使用时才有效。全文搜索引擎会简单地忽略搜索词开头的星号。
          • 感谢您的回答。你忘了莱拉和班德。我可以为此使用 Lucene 吗?
          【解决方案5】:

          您可能想查看Lucene.net 作为全文的替代方案。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2011-06-10
            • 2011-10-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多