【问题标题】:Trying to create a keyword search in PHP and MySQL尝试在 PHP 和 MySQL 中创建关键字搜索
【发布时间】:2013-12-12 18:14:58
【问题描述】:

我正在建立一个具有可搜索产品数据库的网站。为了简单起见,我的表有三列:

  • 身份证
  • img(对产品图片的引用)
  • 标签(varchar 255,用于搜索的标签列表,例如“chair wood brown”)

我有疑问:

$query = "SELECT `img` FROM `products` WHERE `tags` LIKE '%$q%'";

这完全符合我的要求,唯一的问题是,如果标签按搜索顺序排列,它只会选择行。例如,如果有 3 行:

  • 第 1 行带有标签“黑色托盘”
  • 第 2 行带有标签“黑色托盘”
  • 第 3 行带有标签“黑色托盘层”

而您搜索“黑色托盘”,第 1 行和第 3 行都会显示,但不会显示第 2 行。

我正在尝试显示所有三行,无论单词的顺序如何。例如,如果您搜索“黑色托盘”,我希望它们全部显示,但如果您搜索“托盘层”,则只会显示第 3 行。也许这需要重新考虑原始查询,我不确定。

非常感谢!

【问题讨论】:

  • 啊哈,正则表达式的黑暗艺术

标签: php mysql sql


【解决方案1】:

您需要使用功能更强大的MATCH AGAINST。此外,您还可以将所有内容编入索引并提高速度。

请参阅以下页面:

【讨论】:

  • 我刚上学;)
  • 想我会伸出援助之手 ;-)
  • 我也尝试过使用它,但我找不到一种方法,所以它只选择具有所有搜索标签的行,而不是其中的一些。有没有办法做到这一点?非常感谢!
  • MATCH(name) AGAINST('+"black tray"'); 如果你想让他们在一起。这简单地解释了用例:stackoverflow.com/questions/14572375/… 请注意,还有更多选项,只需查看文档,我保证您可以找到所需的内容。
【解决方案2】:

可能为时已晚,但如果可能,请改为使用另一个表格作为标签:

product_id | tag
1          | black
1          | tray
2          | tray
2          | black
3          | black
3          | tray
3          | layer

这将允许您使用以下标签查找任何作为一个或多个标签的产品:

SELECT DISTINCT products.* 
FROM products LEFT JOIN tags ON tags.product_id = products.id 
WHERE tags.tag IN ('black', 'red', 'light')

编辑

如果您希望所有标签都存在,您必须向 x 个标签发出 x 个查询以使用以下方法进行搜索:

SELECT *
FROM
    (SELECT DISTINCT products.* 
    FROM products LEFT JOIN tags ON tags.product_id = products.id 
    WHERE tags.tag = 'black') AS set_a
INNER JOIN
    (SELECT DISTINCT products.* 
    FROM products LEFT JOIN tags ON tags.product_id = products.id 
    WHERE tags.tag ='red') AS set_b ON set_a.product_id = set_b.product_id
INNER JOIN
    (SELECT DISTINCT products.* 
    FROM products LEFT JOIN tags ON tags.product_id = products.id 
    WHERE tags.tag = 'light') AS set_c ON set_b.product_id = set_c.product_id

这将与找到的所有记录相交,只留下潜在记录。请注意,这是一个非常繁重的请求,我不知道是否在 MySQL 中实现了 INTERSECT 关键字,我相信这将是一个更好的方法!

【讨论】:

  • 这行得通,但是它仍然会选择搜索到任何标签的产品,我希望它选择搜索到所有标签的产品。那有意义吗?有没有办法用你的方法做到这一点?感谢您的所有帮助!
  • 这是一个可靠的方法,但我会创建一个缓存表,索引。我会在 InnoDB 中有一个这样的表来利用 FK。但是,您始终可以创建脚本来构建索引的缓存脚本。会快得多,而且您可以利用MATCH AGAINST
  • 如果您希望所有标签都出现在您的搜索中,那是一个完全不同的问题。然后,您必须多次发出相同的请求并使用 INTERSECT,这实际上是两个查询之间的 INNER JOIN。看看我的编辑,很快就会发布!
【解决方案3】:

我建议将单字标签存储在单独的关系(表格)中,并且:

preg_replace('\s+', "','", $q);
$query = "SELECT `img` FROM `products` LEFT JOIN `tags` USING (`id`) WHERE `tags`.`content` IN ('$q')";

【讨论】:

    猜你喜欢
    • 2013-04-08
    • 1970-01-01
    • 2018-12-16
    • 2015-03-07
    • 2011-04-24
    • 2010-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多