我想创建一个我正在处理的网站的简单搜索。我的数据库中的项目都包含特定的类别ID,并且可以选择链接到多个标记。
我想接受任何搜索字词并查询category.name和tag.name字段以查找与这些字词匹配的项目。
我正在寻找有关如何创建有效/快速查询的建议,并按照与最接近(最匹配)匹配的项目对结果进行排序
以下是我相关表格的快速版本:
项目
id |类别|标题|描述
类别
id |名字| parentId的
代码
id |名字|用途
item_tag
itemId | TAGID
答案 0 :(得分: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 string functions来规范化查询;一种方法是用'|'替换','的每一个出现,删除多余的空格并执行以下查询: [我将使用@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等)来做。
答案 1 :(得分: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