Mysql 按类别自定义网站搜索

Mysql 按类别自定义网站搜索,mysql,Mysql,我想为我正在工作的网站创建一个简单的搜索。我的数据库中的项目都有一个特定的类别id,可以选择链接到多个标记 我想使用任何搜索术语,并查询category.name和tag.name字段,以查找与这些术语匹配的项目 我正在寻找有关如何创建高效/快速查询的建议,该查询可以做到这一点,并按最匹配的项(大多数匹配项)对结果进行排序 以下是我的相关表格的快速版本: 项目 id |类别|标题|说明 类别 id |姓名|家长id 标记 id | name |使用 项目标签 itemId | tagId选择项目

我想为我正在工作的网站创建一个简单的搜索。我的数据库中的项目都有一个特定的类别id,可以选择链接到多个标记

我想使用任何搜索术语,并查询category.name和tag.name字段,以查找与这些术语匹配的项目

我正在寻找有关如何创建高效/快速查询的建议,该查询可以做到这一点,并按最匹配的项(大多数匹配项)对结果进行排序

以下是我的相关表格的快速版本:

项目

id |类别|标题|说明

类别

id |姓名|家长id

标记

id | name |使用

项目标签

itemId | tagId

选择项目*
SELECT item.*
FROM items
LEFT JOIN categories
       ON categories.name = '< input name >'
      AND categories.id = items.category
LEFT JOIN item_tags
      AND item_tags.itemId = items.id
LEFT JOIN tags
       ON tags.name = '< input name >'
      AND tags.id = item_tags.tagId
WHERE categories.id IS NOT NULL
   OR tags.id IS NOT NULL
ORDER BY COUNT(items.id) DESC;
从项目 左连接类别 在categories.name=“”上 和categories.id=items.category 左连接项\u标记 和item_tags.itemId=items.id 左连接标记 在tags.name=“”上 AND tags.id=项目_tags.tagId 其中categories.id不为NULL 或tags.id不为空 按计数(items.id)描述的订单;
这可能不是最快的方法。基本上,在确保类别和标记具有正确名称的同时,将类别和标记留给项目。筛选出与where子句中的类别或项目标记不匹配的所有项目


另一种选择是创建临时表。为具有正确名称的所有类别创建一个,并为具有正确名称的所有标记创建一个。然后,您可以在categories\u表中选择items.id或tags\u表中选择items.id的项目

我仍然不完全理解您想要什么。
好的,这是我们要讨论的第一个版本。
我建议您创建如下视图:

CREATE OR REPLACE VIEW `search_view` AS
SELECT
  i.id    AS `item_id`,
  i.title AS `item_title`,
  c.id    AS `cat_id`,
  c.name  AS `cat_name`,
  t.id    AS `tag_id`,
  t.name  AS `tag_name`
FROM item AS i
LEFT OUTER JOIN item_tag AS it
  ON (i.id = it.itemId)
LEFT OUTER JOIN tag AS t
  ON (it.tagId = t.id)
LEFT OUTER JOIN category AS c
  ON (i.category = c.id)
WHERE ((t.id IS NOT NULL) OR (c.id IS NOT NULL));
然后使用附近的东西从视图中进行查询

SELECT
  *,
  (
    IF(tag_name like ?, 2, 0)
    + IF(cat_name like ?, 4, 0)
    + IF(item_title like ?, 1, 0)
  ) AS `priority`
  FROM search_view
GROUP BY item_id
ORDER BY SUM(priority);
上面的代码中没有测试。报告你遇到的任何问题

[第一版]您使用PHP,是吗? 那么,您可以使用规范化查询;一种方法是将每次出现的“,”替换为“|”,删除额外的空格并执行以下查询:[我将使用@VAR给出一个示例(实际上您将用输入字符串替换它)]


这次我考了。是的,您可以使用MySQL函数,关于
REPLACE(REPLACE(@VAR,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,)
。但我建议您使用PHP(或java、python等)进行此操作。

我认为这将使我走上正确的道路,但table item_标记只将标记映射到项目,因此需要加入标记表来搜索名称,我还没有真正使用视图。上面的部分是需要在每次查询之前运行还是在创建连接时只运行一次?我非常喜欢您的解决方案以及您添加了标题搜索并为不同字段赋予权重的事实。如果你有机会,你愿意解释一下我如何修改它来处理多个搜索词吗?它们将以逗号分隔的字符串形式出现。@Helto,您只需创建一次视图,然后就可以从中进行查询,就像它们是公共表一样(!)。如果需要更新视图,只需运行:
CREATE或REPLACE view AS
。关于你最后的疑问,我会尽力帮助你当我有时间(今天,如果可能的话)(让我们看看我是否可以)做!看看它是否有效,如果您想要{ER图、SQL脚本和我做的触发器,请发邮件给我[为什么我要做触发器?For tag.uses column(只是为了好玩)]哇,谢谢,我会尽快尝试。是的,我正在使用php/PDO
SET @VAR = 'notebook|samsung';
SELECT
  *,
  (
    IF (tag_name REGEXP CONCAT('.*(', @VAR, ').*'), 2, 0)
    + IF (cat_name REGEXP CONCAT('.*(', @VAR, ').*'), 4, 0)
    + IF (item_title REGEXP CONCAT('.*(', @VAR, ').*'), 1, 0)
  ) AS `priority`
  FROM search_view
ORDER BY priority DESC;