2010-01-13 70 views
3

我正在寻找一个很好的解决方案,以有效地使用SQL Server r2005的containstable功能。目前我有,例如员工和地址表。在多个表和列上的SQL Server 2005全文搜索

-Employee 
Id 
Name 

-Address 
Id 
Street 
City 
EmployeeId 

现在用户只能在一个文本框中输入搜索条件,我希望使用“AND”运算符来拆分和搜索这些条款。 FREETEXTTABLE似乎自动处理“或”。

现在让我们说用户输入“John Hamburg”。这意味着他想在汉堡找到约翰。 所以这是“John AND 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

我有同样的问题。这是我的解决方案,它适用于我的情况:

我创建了一个视图,它返回我想要的列。我添加了另一个额外的列,它汇总了我想要搜索的所有列。因此,在这种情况下,视图将会像

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] 
6

这是更多的语法问题。你如何用一个输入框来描述用户的意图?

  • 他们在找“John Hamburg”这个人吗?
  • 他们在寻找“约翰汉堡街”吗?
  • 他们是在寻找住在斯普林菲尔德“汉堡街”的“约翰”吗?
  • 他们是否在寻找住在“汉堡”城市的“约翰”?

不知道用户的意图,最好的你可以期望的是或者这些条款,并采取最高排名点击。

否则,你需要在一吨的逻辑编程,这取决于传入的单词数:

2个字:

足月1搜寻员工数据,搜索的员工数据项2,术语1的搜索地址数据,术语2的搜索地址数据。按术语合并结果,按大部分命中排序。

3个词语:

为术语1搜索员工的数据,术语2搜索员工的数据,术语3搜索雇员的数据,术语1搜索地址数据,搜索术语2地址数据,用于搜索地址数据term 3.按照术语合并结果,按大多数命中顺序。

等等

我想我会重新设计了GUI的输入分成的名称和地址,在最低限度。如果这是不可能的,强制执行的语法规则的效果

EDIT“第01话将被视为一个名字,直到出现一个逗号,将被视为地址后的任何话”:

您最好的选择仍然是或条款,并采取最高排名命中。下面是这方面的一个例子,一个例子,为什么这是不理想的,而不输入一些预处理占卦用户的意图:

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) 

现在,因为我们不知道哪些关键字将适用于什么表,我们必须假设他们可以适用于任何一个表,所以我们必须对每个表进行OR运算,UNION结果,聚合它们并计算最高排名。

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 

这是不太理想,这里就是你的例子(你的情况,你会从汉堡想李四先出现):

Id  Name    Street   City   Rank 
2  John Smith  Hamburg St.  Springville 112 
3  Bob Hamburg  St. John Ave.  Springville 112 
5  John Doe   Oak Lane   Hamburg  96 
1  John Hamburg  Main St.   Springville 48 
4  Bob Smith   5th Ave.   Hamburg  48 

但这是最好的,你可以在提交给SQL之前解析输入,以便根据用户的需求做出“最佳猜测”。

+1

感谢您的回复。我想保留一个输入框,因为用户应该很容易在Google中搜索真正快速的内容。如果用户搜索约翰汉堡,他想要得到结果 约翰谁住在汉堡 约翰谁的姓可能是汉堡和谁可能住在汉堡 但没有结果 只是约翰谁不住在汉堡。 或者住在汉堡的其他人。 事情是,稍后会有更多的信息可以像电子邮件等搜索。因此,我需要一个包含所有数据一次包含由AND连接的术语的containstable。 – Chris 2010-01-13 22:51:29

+0

回到语法。如果您不知道输入关键字应该应用于哪个表和列,则无法在大量逻辑中进行编程而无法创建“通用”AND语句。在上面的例子中,您如何知道将第一个关键字搜索为[Name],将第二个关键字搜索为[City]?如果用户希望第二个关键字成为名称的一部分,或者是街道的一部分,该怎么办?除非你有一些你没有提到的语法规则,否则这些规则说明了什么“第一个词将是一个名字,第二个词将是一个城市”? – GalacticJello 2010-01-14 16:21:56

+0

@Chris每当我看到“像Google一样”这个短语时,我的回答总是一样的:如果在Google上创建'like'逻辑很容易在stackoverflow上回答,那么他们就不会聘用数千名高薪的开发者。不要指望能够在短短几天内复制这种质量。 – ean5533 2011-12-07 14:48:43

相关问题