SQL Server全文搜索 - 创建一个计算列 [英] SQL Server Full Text Search - Create one computed column

查看:120
本文介绍了SQL Server全文搜索 - 创建一个计算列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在研究一个项目,我只想通过一个输入搜索词搜索员工。为此,我使用SQL FTS。



表模式如下所示:

员工表
$ b EmployeeId,名字,姓氏

示例数据 p>

<1>,John,Miller


2,Chuck,Norris




地址表



AddressId,EmployeeId,CityId,Street,StreetNumber



样本数据

<1>,1,Avenue,12

b
$ b 2,2,2温布尔登路12,

$ hr
$ b

城市表格

CityId,Name,ZipCode

示例数据



<1>,汉堡22335

2,伦敦12345





所以现在我得到了以下搜索词:




  • John Hamburg:意思是约翰和汉堡,并应该返回1条记录。

  • 约翰伦敦:意味着约翰和隆多n,并且应该返回0条记录,因为在伦敦没有约翰。

  • Norris Wimbledon:意味着Norris和Wimbledone,并且应该返回1条记录。

    现在问题在于使用CONTAINSTABLE只允许一次搜索一个表。因此,在员工全文目录中应用John AND Hamburg后,由于汉堡位于地址表中,因此将返回0条记录。

    因此,目前我可以使用OR而不是AND,如:

      SELECT 
    (keyTblSp.RANK * 3)AS [Rank],
    sp。*
    FROM员工sp
    内部加入
    CONTAINSTABLE(员工,*,'John OR Hamburg',1000)AS keyTblSp
    ON sp.EmployeeId = keyTblSp 。[KEY]

    UNION ALL
    SELECT
    (keyTbl.RANK * 2)AS [Rank],
    sp。*
    FROM员工sp
    LEFT OUTER JOIN [Address] addr ON addr.EmployeeId = sp.EmployeeId
    INNER JOIN
    CONTAINSTABLE([Address],*,'John OR Hamburg',1000)AS keyTbl
    ON addr.AddressId = keyTbl。[KEY]
    UNION ALL
    SELECT
    (keyTbl.RANK * 2)AS [Rank],
    sp。*
    FROM Employee sp
    LEFT OUTER JOIN [地址] addr ON addr.EmployeeId = sp.EmployeeId
    L EFT OUTER JOIN [City] cty ON cty.CityId = addr.CityId
    INNER JOIN
    CONTAINSTABLE([City],*,'John OR Hamburg',1000)AS keyTbl
    ON cty。 CityId = keyTbl。[KEY]

    这会导致不仅仅是返回汉堡的John,名叫约翰的人和住在汉堡的每一个人。
    我能想到的一个解决方案是以某种方式计算员工表中的一列,其中包含全文搜索的所有必要值。



    雇员表



    EmployeeId,名字,姓氏, FulltextColumn

    示例数据


    1 |约翰|米勒| John Miller Avenue 12汉堡22335



    然后我可以做

    pre > SELECT
    (keyTbl.RANK)AS [Rank],
    sp。*
    FROM员工sp
    INNER JOIN
    CONTAINSTABLE([Employee ],FulltextColumn,'John AND Hamburg',1000)AS keyTbl
    ON sp.EmployeeId = keyTbl。[KEY]

    这可能吗?任何其他想法?

    解决方案

    您可以使用连接来要求地址和人员名称匹配。

      SELECT 
    (keyTblSp.RANK * 3)AS [Rank],
    sp。*
    FROM员工sp
    INNER JOIN
    CONTAINSTABLE(Employee,*,'John OR Hamburg',1000)AS keyTblSp
    ON sp.EmployeeId = keyTblSp。[KEY]
    join

    SELECT
    (keyTbl.RANK * 2)AS [Rank],
    sp。*
    FROM员工sp
    LEFT OUTER JOIN [地址] addr ON addr .EmployeeId = sp.EmployeeId
    INNER JOIN
    CONTAINSTABLE([Address],*,'John OR Hamburg',1000)AS keyTbl
    ON addr.AddressId = keyTbl。[KEY]
    UNION ALL
    SELECT
    (keyTbl.RANK * 2)AS [Rank],
    sp。*
    FROM员工sp
    LEFT OUTER JOIN [Address] addr ON addr.EmployeeId = sp.EmployeeId
    LEFT OUTER JOIN [City] cty ON cty .CityId = addr.CityId
    INNER JOIN
    CONTAINSTABLE([City],*,'John OR Hamburg',1000)AS keyTbl
    ON cty.CityId = keyTbl。[KEY]
    )addr_matches
    on addr_matches.EmployeeId = sp.EmployeeId

    我认为会给你明确了你所指定的结果,但是这要求搜索的名称和地址搜索条件都返回任何结果。你没有说明如果有人只是搜索'约翰',如果你总是会得到一个姓名和地址,会发生什么事情,我认为上述将工作正常。

    I am currently working on a project where I want to search for employees via just one input search term. For this I am using the SQL FTS.

    The table schema looks like this

    Employee table

    EmployeeId, Firstname, Lastname

    Sample data

    1, John, Miller

    2, Chuck, Norris


    Address table

    AddressId, EmployeeId, CityId, Street, StreetNumber

    Sample data

    1, 1, 1, Avenue, 12

    2, 2, 2, Wimbledon Rd, 12


    City table

    CityId, Name, ZipCode

    Sample data

    1, Hamburg, 22335

    2, London, 12345


    So now I got the following search term:

    • John Hamburg: Means John AND Hamburg and should return 1 record.
    • John London: Means John AND London and should return 0 records since there is no John in London.
    • Norris Wimbledon: Means Norris AND Wimbledone and should return 1 records.

    Now the problem with this is that using CONTAINSTABLE only allows to search one table at a time. So applying "John AND Hamburg" on the Employee Full text catalog returns 0 records since "Hamburg" is located in the address table.

    So currently I can use "OR" instead of "AND" only, like:

    SELECT
       (keyTblSp.RANK * 3) AS [Rank],
        sp.*
    FROM Employee sp    
        INNER JOIN 
            CONTAINSTABLE(Employee, *, 'John OR Hamburg', 1000) AS keyTblSp
            ON sp.EmployeeId = keyTblSp.[KEY]    
    
    UNION ALL
    SELECT
       (keyTbl.RANK * 2) AS [Rank],
        sp.*
    FROM Employee sp    
        LEFT OUTER JOIN [Address] addr ON addr.EmployeeId = sp.EmployeeId 
        INNER JOIN 
            CONTAINSTABLE([Address], *, 'John OR Hamburg', 1000) AS keyTbl
            ON addr.AddressId = keyTbl.[KEY]    
    UNION ALL
    SELECT
       (keyTbl.RANK * 2) AS [Rank],
        sp.*
    FROM Employee sp    
        LEFT OUTER JOIN [Address] addr ON addr.EmployeeId = sp.EmployeeId 
        LEFT OUTER JOIN [City] cty ON cty.CityId = addr.CityId
        INNER JOIN 
            CONTAINSTABLE([City], *, 'John OR Hamburg', 1000) AS keyTbl
            ON cty.CityId = keyTbl.[KEY]  
    

    This causes that not just John who lives Hamburg is returned, but every person named John and every person who lives in Hamburg. One solution I could think of is to somehow compute a column in the Employee Table that holds all necessary values for the full text search like.

    Employee table

    EmployeeId, Firstname, Lastname, FulltextColumn

    Sample data

    1 | John | Miller | John Miller Avenue 12 Hamburg 22335

    So then I could do

    SELECT
       (keyTbl.RANK) AS [Rank],
        sp.*
    FROM Employee sp    
        INNER JOIN 
            CONTAINSTABLE([Employee], FulltextColumn, 'John AND Hamburg', 1000) AS keyTbl
            ON sp.EmployeeId = keyTbl.[KEY] 
    

    Is this possible? Any other ideas?

    解决方案

    you could use a join to require a match in both the address and the persons name.

    SELECT
       (keyTblSp.RANK * 3) AS [Rank],
        sp.*
    FROM Employee sp    
        INNER JOIN 
            CONTAINSTABLE(Employee, *, 'John OR Hamburg', 1000) AS keyTblSp
            ON sp.EmployeeId = keyTblSp.[KEY]    
    join
    (
        SELECT
           (keyTbl.RANK * 2) AS [Rank],
            sp.*
        FROM Employee sp    
        LEFT OUTER JOIN [Address] addr ON addr.EmployeeId = sp.EmployeeId 
        INNER JOIN 
            CONTAINSTABLE([Address], *, 'John OR Hamburg', 1000) AS keyTbl
            ON addr.AddressId = keyTbl.[KEY]
    UNION ALL
        SELECT
           (keyTbl.RANK * 2) AS [Rank],
            sp.*
        FROM Employee sp    
        LEFT OUTER JOIN [Address] addr ON addr.EmployeeId = sp.EmployeeId 
        LEFT OUTER JOIN [City] cty ON cty.CityId = addr.CityId
        INNER JOIN 
            CONTAINSTABLE([City], *, 'John OR Hamburg', 1000) AS keyTbl
            ON cty.CityId = keyTbl.[KEY]  
    ) addr_matches
    on addr_matches.EmployeeId = sp.EmployeeId
    

    which I think would give you the results you specified, obviously though, this requires both a name and an address search term for a search to return any results. You didn't specify what happens if someone just searches for 'John', if you will always get both a name and address the above will work fine I think.

    这篇关于SQL Server全文搜索 - 创建一个计算列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆