【问题标题】:SQL Full text Search with phrases, prefix_term on multiple columnsSQL全文搜索与短语,prefix_term多列
【发布时间】:2016-07-14 16:22:47
【问题描述】:

我的应用程序将客户姓名存储在 3 列中,但搜索使用单个参数触发。我正在尝试实现 FULLTEXT 搜索以有效地在此客户数据库中进行搜索。

我在找名字

里玛侯赛因

我使用下面的 TSQL 来搜索起始词。

SELECT 
    REM_ID, REM_FNAME, REM_MNAME, REM_LNAME 
FROM 
    dbo.tblM_REMMASTER 
WHERE 
    CONTAINS((REM_FNAME , REM_MNAME, REM_LNAME) ,'"RIMA*"')

查询按预期工作,为我提供了良好的搜索结果。

如果我提供带有短语的更新查询,这种情况不会为我提供任何结果。

为尝试解决方案而执行的示例测试查询。

SELECT 
    REM_ID, REM_FNAME, REM_MNAME, REM_LNAME 
FROM 
    dbo.tblM_REMMASTER 
WHERE 
    CONTAINS((REM_FNAME , REM_MNAME, REM_LNAME), '"rima*" AND "*hussein"') 

SELECT 
    REM_ID, REM_FNAME, REM_MNAME, REM_LNAME  
FROM 
    dbo.tblM_REMMASTER 
WHERE 
   CONTAINS(REM_FNAME  ,'"RIMA HUSSEIN"')

SELECT 
    REM_ID, REM_FNAME, REM_MNAME, REM_LNAME 
FROM 
    dbo.tblM_REMMASTER 
WHERE 
    CONTAINS((REM_FNAME , REM_MNAME, REM_LNAME)  ,'NEAR ((RIMA,HUSSEIN),MAX,TRUE)')

以前有没有人遇到过这个问题,或者在这个特定的场景下可以实现什么样的解决方案逻辑?

在没有全文的实时环境中测试的示例查询:

SET @NAME=N'RIMAHUSSEIN'

SELECT  
    REM_ID, REM_FNAME, REM_MNAME, REM_LNAME 
FROM 
    dbo.tblM_REMMASTER WITH (READPAST) 
WHERE
    ((LTRIM(RTRIM(REM_FNAME)) +  LTRIM(RTRIM(REM_MNAME)) + LTRIM(RTRIM(REM_LNAME)) LIKE '%' + @NAME + '%'))

【问题讨论】:

  • 你能把名字输入的第一个、中间和最后一个组件分开,并在每个组件上使用LIKE吗?
  • 准确显示每个条件应该做什么。您可以尝试使用 LIKE。

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


【解决方案1】:

我们的应用程序必须在表的几乎每一列中进行搜索,因此我们创建了一个视图 WITH SCHEMABINDINGCLUSTERED INDEX,其结构如下:

CREATE VIEW search_view
WITH SCHEMABINDING
AS
SELECT  id,
        column1 + ' ' + column2 + etc as search_text
FROM table

CREATE CLUSTERED INDEX ci_id ON search_view (id);

并将全文索引放在search_text 列上。 然后我们就:

SELECT ...
FROM table t
INNER JOIN CONTAINSTABLE(search_view, search_text, '"word1*" AND "word2*" ... ') AS sv
    ON t.ID = sv.ID

【讨论】:

  • 这是最合适的答案,但我担心速度慢。创建视图时会发生这种情况吗?在大多数情况下,该表的平均案例数接近 15 - 2000 万。
  • 创建时 - 不,使用视图时 - 可能会出现问题。例如,在我们看来,我们连接了超过 10 列,其中大多数是nvarchar(max),行数约为 150k,并且每天都在增加(每天增加 100-200 行)。用户每天提出约 400 个请求。查询的平均响应时间约为 500 毫秒。
【解决方案2】:

试一试..

SELECT * FROM dbo.tblM_REMMASTER WHERE CONTAINS((REM_FNAME,REM_MNAME, REM_LNAME) ,'"RIMA*"') 
AND  CONTAINS((REM_FNAME , REM_MNAME, REM_LNAME), '"*hussein"') 

【讨论】:

  • OR 在结果集中返回一条巨大的记录,但是当搜索子句中有三个单词时,AND 提供了准确的结果但不能完全解决问题。此外,查询是在单个变量中从应用程序传递的,如查询中所示,而不使用全文
猜你喜欢
  • 2016-01-26
  • 2015-02-05
  • 1970-01-01
  • 2010-10-03
  • 1970-01-01
  • 2014-02-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多