0

我想为我正在处理的网站创建一个简单的搜索。我的数据库中有所有项目都包含特定的类别 ID,并且可以选择链接到多个标签。

我想获取任何搜索词并查询 category.name 和 tag.name 字段以找到与这些词匹配的项目。

我正在寻找有关如何创建执行此操作的高效/快速查询的建议,并按最接近的匹配项(大多数匹配项)对结果进行排序

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

物品

编号 | 类别 | 标题 | 描述

类别

编号 | 姓名 | 父母身份

标签

编号 | 姓名 | 用途

item_tag

项目 ID | 标记ID

4

2 回答 2

1

我还是没完全明白你想要什么。
好吧,这是我们讨论的第一个版本。
我建议您创建如下视图:

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,不是吗?好吧,您可以使用PHP 字符串函数规范化您的查询;一种方法是将每次出现的 ',' 替换为 '|',删除多余的空格并执行以下查询:[我将举一个使用 @VAR 的示例(实际上您将用输入字符串替换它)]

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;

这次我测试了。是的,你可以使用 MySQL 函数,关于REPLACE(REPLACE(@VAR,' ',''), ',', '|'). 但我建议你用 PHP(或 java、python 等)来做。

于 2013-03-23T06:05:34.443 回答
0
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;

这可能不是最快的方法。基本上,您将在确保类别和标签具有正确名称的同时将连接类别和标签留给项目。过滤掉与 where 子句中的类别或 item_tag 不匹配的所有项目。

另一种选择是创建临时表。为具有正确名称的所有类别创建一个,并为具有正确名称的所有标签创建一个。然后你可以选择项目 WHERE items.id IN categories_table OR items.id IN tags_table

于 2013-03-23T02:56:25.627 回答