全文确定匹配的字段

时间:2013-03-15 15:29:59

标签: mysql full-text-search

我有一个表设置,其中包含ID,StreetNumber,StreetName,StreetType的全文索引,用于实时表单搜索。示例数据如下所示:

       ID        StreetNumber   StreetName   StreetType
   -----------------------------------------------------
   | 141099  |        1411   |  Elm       |      ST    |
   -----------------------------------------------------
   | 141100  |        2901   |  Maple     |      LN    |
   -----------------------------------------------------

如果我查询使用:

SELECT ID, StreetName, StreetNumber, StreetType
FROM Locations
WHERE MATCH(ID, StreetName, StreetNumber, StreetType)
      AGAINST('1411*' IN BOOLEAN MODE)

它当然会返回两个记录......但是,我很难找到一种简单的方法来确定它匹配的字段。

我想将我的实时搜索结果格式化为:

ID: 141100 (2901 Maple Lane)
Address: 1411 Elm St

...按照匹配的内容排序。在PHP格式化很容易,它找到的结果与问题相匹配。但是,我无法找到一种方法来做到这一点,而无需在PHP中检查它(效率不高)。想法?

1 个答案:

答案 0 :(得分:1)

您可以使用全文索引有效地进行搜索,然后使用另一个解决方案来测试列的选择列表(仅针对在WHERE子句中传递过滤器的行运行):

SELECT ID, StreetName, StreetNumber, StreetType,
  (StreetName like '%1411%') AS `StreetName_matches`, 
  (StreetNumber like '%1411%') AS `StreetNumber_matches`,
  (StreetType like '%1411%') AS `StreetType_matches`
FROM Locations 
WHERE MATCH(ID, StreetName, StreetNumber, StreetType) 
      AGAINST('1411*' IN BOOLEAN MODE)

或者您可以在列上创建四个单独的全文索引,并依次搜索每个索引:

SELECT ID, StreetName, StreetNumber, StreetType,
  MAX(`ID_Matches`) AS `ID_Matches`,
  MAX(`StreetName_Matches`) AS `StreetName_Matches`,
  MAX(`StreetNumber_Matches`) AS `StreetNumber_Matches`,
  MAX(`StreetType_Matches`) AS `StreetType_Matches`
FROM (
  SELECT SELECT ID, StreetName, StreetNumber, StreetType,
    1 AS `ID_Matches`,
    NULL AS `StreetName_Matches`,
    NULL AS `StreetNumber_Matches`,
    NULL AS `StreetType_Matches`
  FROM Locations 
  WHERE MATCH(ID) AGAINST('1411*' IN BOOLEAN MODE)
  UNION ALL
  SELECT SELECT ID, StreetName, StreetNumber, StreetType,
    NULL AS `ID_Matches`,
    1 AS `StreetName_Matches`,
    NULL AS `StreetNumber_Matches`,
    NULL AS `StreetType_Matches`,
  FROM Locations 
  WHERE MATCH(StreetName) AGAINST('1411*' IN BOOLEAN MODE)
  UNION ALL
  SELECT SELECT ID, StreetName, StreetNumber, StreetType,
    NULL AS `ID_Matches`,
    NULL AS `StreetName_Matches`,
    1 AS `StreetNumber_Matches`,
    NULL AS `StreetType_Matches`,
  FROM Locations 
  WHERE MATCH(StreetNumber) AGAINST('1411*' IN BOOLEAN MODE)
  UNION ALL
  SELECT SELECT ID, StreetName, StreetNumber, StreetType,
    NULL AS `ID_Matches`,
    NULL AS `StreetName_Matches`,
    NULL AS `StreetNumber_Matches`,
    1 AS `StreetType_Matches`,
  FROM Locations 
  WHERE MATCH(StreetTYPE) AGAINST('1411*' IN BOOLEAN MODE)
) AS t
GROUP BY t.ID;

您可能还希望研究功能更全面的全文搜索技术,例如Sphinx SearchApache Solr

例如,请参阅How to return column that matched the query in Solr..?

的答案