MySQL全文搜索多列:结果混乱

时间:2013-07-03 22:45:43

标签: mysql full-text-search

我有一个搜索查询,可以在数据库上执行全文搜索。

$sql = "SELECT
*
FROM 
`tbl_auction_listing` AS `al` 
JOIN 
`tbl_user` AS `u` ON `al`.`user_id` = `u`.`user_id` 
LEFT JOIN
`tbl_gallery_details` AS `gd` ON `al`.`user_id` = `gd`.`user_id`
LEFT JOIN
`tbl_self_represented_details` AS `sr` ON `u`.`user_id` = `sr`.`user_id`
WHERE 
`al`.`status` = '" . ACTIVE . "'
AND
`al`.`start_date` < NOW() 
AND
`al`.`end_date` > NOW()
AND
MATCH(`al`.`listing_title`,
`al`.`description`,
`al`.`provenance`,
`al`.`title`,
`al`.`artist_full_name`,
`al`.`artist_first_name`,
`al`.`artist_last_name`,
`sr`.`artist_name`,
`gd`.`gallery_name`,
`u`.`username`) AGAINST('$search_query' IN BOOLEAN MODE)";

当我搜索'Cardozo,Horacio'或'cardozo'或'horacio'时,我没有得到任何结果,但我知道在db中有一个艺术家有2条记录,其中artist_full_name = Cardozo,Horacio。

如果我删除所有MATCH字段并且只有alartist_full_name我会得到2个结果。如果我添加aldescription我得到1个结果,因为描述中存在“Horacio Cardozo”。

如果在任何MATCH字段中满足任何条件(任何搜索查询字),是否有办法让搜索返回所有记录?我尝试删除IN BOOLEAN MODE但产生了相同的结果。

1 个答案:

答案 0 :(得分:19)

似乎InnoDB表不允许在同一MATCH()条件下搜索多个全文索引。

此处您的字段并非都属于同一个表,因此它们由不同的索引覆盖。请注意,如果您有这样的表,则同样的限制适用:

CREATE TABLE t (
  f1 VARCHAR(20),
  f2 VARCHAR(20),
  FULLTEXT(f1), FULLTEXT(f2)
) ENGINE=InnoDB;

SELECT * FROM t
WHERE MATCH(f1, f2) AGAINST ('something in f2'); -- likely to return no row

看起来全文搜索只能搜索遇到的第一个全文索引,但这只是我扣除的from this experience ,请不要带这是理所当然的。

最重要的是,您应该拆分搜索,以便根据MATCH()子句使用单个全文索引:

SELECT * FROM auction, user, gallery, ...
WHERE
    MATCH(auction.field1, auction.field2) AGAINST ('search query' IN BOOLEAN MODE) OR
    MATCH(auction.field3) AGAINST ('search query' IN BOOLEAN MODE) OR
    MATCH(user.field1, user.field2, user.field3) AGAINST...

如果auction上有两个不同的索引,user上有一个不同的索引,则会显示可能的查询。您需要根据实际结构进行调整(如果您需要更多指导,请发布表格说明)。

请注意,这仅适用于InnoDB表。有趣的是,MyISAM表do not seem to show the same limitation


更新:事实证明这是a bug in the InnoDB engine,修正在5.6.13 / 5.7.2中。上面的示例现在正确地失败,“找不到与列列表匹配的FULLTEXT索引”。实际上,(f1, f2)上没有索引,但(f1)上有一个索引,(f2)上有另一个索引。 As the changelog advises

  

与MyISAM不同,InnoDB不支持布尔全文搜索   非索引列,但未强制执行此限制   在返回错误结果的查询中。

值得注意的是,虽然此类查询使用MyISAM返回正确的结果集,但它们的运行速度比人们预期的要慢they silently ignore existing fulltext indexes