SQL Server 2005在多个表和列上进行全文搜索

SQL Server 2005在多个表和列上进行全文搜索,sql,sql-server,tsql,full-text-search,Sql,Sql Server,Tsql,Full Text Search,我正在寻找一个好的解决方案,以便有效地使用SQLServeR2005的containstable特性。目前,我有一名员工和一个地址表 -Employee Id Name -Address Id Street City EmployeeId 现在,用户只能在一个文本框中输入搜索词,我希望将这些词拆分并使用“and”运算符进行搜索。FREETEXTTABLE似乎可以自动使用“或” 现在假设用户输入了“John Hamburg”。这意味着他想在汉堡找到约翰。 这就是《约翰和汉堡》 因此,以下内容将

我正在寻找一个好的解决方案,以便有效地使用SQLServeR2005的containstable特性。目前,我有一名员工和一个地址表

-Employee
Id
Name

-Address
Id
Street
City
EmployeeId
现在,用户只能在一个文本框中输入搜索词,我希望将这些词拆分并使用“and”运算符进行搜索。FREETEXTTABLE似乎可以自动使用“或”

现在假设用户输入了“John Hamburg”。这意味着他想在汉堡找到约翰。 这就是《约翰和汉堡》

因此,以下内容将不包含任何结果,因为CONTAINSTABLE会检查每一列中的“John AND Hamburg”

所以我的问题是:在多个列/表中使用AND运算符执行全文搜索的最佳方法是什么

SELECT *
FROM Employee emp
    INNER JOIN 
        CONTAINSTABLE(Employee, *, '(JOHN  AND Hamburg)', 1000) AS keyTblSp
        ON sp.ServiceProviderId = keyTblSp.[KEY]    
    LEFT OUTER JOIN [Address] addr ON addr.EmployeeId = emp.EmployeeId
UNION ALL
SELECT *
FROM Employee emp 
    LEFT OUTER JOIN [Address] addr ON addr.EmployeeId = emp.EmployeeId
    INNER JOIN 
        CONTAINSTABLE([Address], *, '(JOHN  AND Hamburg)', 1000) AS keyTblAddr
        ON addr.AddressId = keyTblAddr.[KEY]    

...

这更像是一个语法问题。你如何通过一个输入框来预测用户的意图

  • 他们在找“约翰·汉堡”这个人吗
  • 他们在找“约翰汉堡街”吗
  • 他们在找住在斯普林菲尔德“汉堡街”的“约翰”吗
  • 他们在找住在汉堡市的“约翰”吗
在不知道用户意图的情况下,您所能期望的最好结果就是访问或使用条款,并获得最高排名的点击率

否则,您需要根据传入的字数在大量逻辑中编程:

2个字:

搜索术语1的员工数据,搜索术语2的员工数据,搜索术语1的地址数据,搜索术语2的地址数据。按术语合并结果,按点击次数排序

三个字:

搜索术语1的员工数据,搜索术语2的员工数据,搜索术语3的员工数据,搜索术语1的地址数据,搜索术语2的地址数据,搜索术语3的地址数据。按术语合并结果,按点击次数排序

等等

我想我应该重新设计GUI,至少将输入分离为名称和地址。如果这是不可能的,强制执行一个语法规则,大意是“在出现逗号之前,第一个单词将被视为名称,其后的任何单词都将被视为地址”

编辑:

你的最佳选择是仍然或条款,并采取最高排名的点击率。下面是一个例子,也是一个例子,说明如果没有对输入进行一些预处理来预测用户的意图,这是不理想的:

insert into Employee (id, [name]) values (1, 'John Hamburg')
insert into Employee (id, [name]) values (2, 'John Smith')
insert into Employee (id, [name]) values (3, 'Bob Hamburg')
insert into Employee (id, [name]) values (4, 'Bob Smith')
insert into Employee (id, [name]) values (5, 'John Doe')

insert into Address (id, street, city, employeeid) values (1, 'Main St.', 'Springville', 1)
insert into Address (id, street, city, employeeid) values (2, 'Hamburg St.', 'Springville', 2)
insert into Address (id, street, city, employeeid) values (3, 'St. John Ave.', 'Springville', 3)
insert into Address (id, street, city, employeeid) values (4, '5th Ave.', 'Hamburg', 4)
insert into Address (id, street, city, employeeid) values (5, 'Oak Lane', 'Hamburg', 5)
现在,由于我们不知道哪些关键字将应用于哪个表,我们必须假设它们可以应用于任何一个表,因此我们必须对每个表使用或项,合并结果,聚合结果,并计算最高秩

SELECT Id, [Name], Street, City, SUM([Rank])
FROM
(
    SELECT emp.Id, [Name], Street, City, [Rank]
    FROM Employee emp 
    JOIN [Address] addr ON emp.Id = addr.EmployeeId
    JOIN CONTAINSTABLE(Employee, *, 'JOHN OR Hamburg') AS keyTblEmp ON emp.Id = keyTblEmp.[KEY]

    UNION ALL

    SELECT emp.Id, [Name], Street, City, [Rank]
    FROM Employee emp 
    JOIN [Address] addr ON emp.Id = addr.EmployeeId
    JOIN CONTAINSTABLE([Address], *, 'JOHN OR Hamburg') AS keyTblAdd ON addr.Id = keyTblAdd.[KEY]   
) as tmp

GROUP BY Id, [Name], Street, City
ORDER BY SUM([Rank]) DESC
这不太理想,以下是您得到的示例(在您的案例中,您希望来自汉堡的John Doe首先出现):


但是,在将输入提交给SQL之前,不必对其进行解析,就可以对用户想要的内容进行“最佳猜测”。

我也遇到了同样的问题。以下是我的解决方案,它适用于我的案例:

我创建了一个返回所需列的视图。我添加了另一个额外的列,它聚合了我要在其中搜索的所有列。因此,在这种情况下,视图将是

SELECT emp.*, addr.*, ISNULL(emp.Name,'') + ' ' + ISNULL(addr.City, '') AS SearchResult 
FROM Employee emp 
    LEFT OUTER JOIN [Address] addr ON addr.EmployeeId = emp.EmployeeId
在此之后,我在SearchResult列上创建了全文索引。然后,我搜索这个专栏

SELECT *
FROM vEmpAddr ea
INNER JOIN CONTAINSTABLE(vEmpAddr, *, 'John AND Hamburg') a ON ea.ID = a.[Key]

谢谢你的回复。我想保留一个输入框,因为它应该很容易让用户搜索像谷歌一样快速的东西。如果用户搜索John Hamburg,他希望得到John的搜索结果,例如,住在汉堡的John姓可能是Hamburg,也可能住在汉堡,但没有找到不住在汉堡的John的搜索结果。或者住在汉堡的其他人。问题是,以后可以搜索更多信息,如电子邮件等。因此,我需要一个包含所有数据的containstable,其中的术语由AND连接,返回语法。如果您不知道输入关键字应该应用于哪个表和列,那么如果不使用大量逻辑进行编程,就无法创建“一刀切”的and语句。在上面的例子中,您如何知道将第一个关键字搜索为[Name],将第二个关键字搜索为[City]?如果用户希望第二个关键字成为名称的一部分或街道的一部分,该怎么办?除非你有一些你没有提到的语法规则,大意是“第一个单词是名字,第二个单词是城市”@Chris每当我在Google中看到短语
like
时,我的回答总是一样的:如果在Google中创建
like
逻辑很容易回答stackoverflow,他们不会雇佣成千上万的高薪开发者。别指望能在几天内复制这种质量。@ean5533我知道,我不想再创建第二个谷歌了。我提到谷歌只是为了强调,我需要一个技术解决方案来搜索存储在一个关系模型中的大量数据,而这个模型只有一个文本框。
SELECT *
FROM vEmpAddr ea
INNER JOIN CONTAINSTABLE(vEmpAddr, *, 'John AND Hamburg') a ON ea.ID = a.[Key]