SQL Server 2005在多个表和列上进行全文搜索
我正在寻找一个好的解决方案,以便有效地使用SQLServeR2005的containstable特性。目前,我有一名员工和一个地址表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”。这意味着他想在汉堡找到约翰。 这就是《约翰和汉堡》 因此,以下内容将
-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]
...
这更像是一个语法问题。你如何通过一个输入框来预测用户的意图
- 他们在找“约翰·汉堡”这个人吗李>
- 他们在找“约翰汉堡街”吗
- 他们在找住在斯普林菲尔德“汉堡街”的“约翰”吗李>
- 他们在找住在汉堡市的“约翰”吗
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]