2013-03-23 115 views
0

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

我想采取任何搜索词进来,并查询category.name和tag.name字段来查找匹配这些条款的项目。

我正在寻找咨询如何建立一个高效/快速查询,这是否和订单的匹配最接近该项目的结果(最匹配)

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

item

id |类别|标题|说明

类别

ID |名称| parentId的

标签

ID |名称|使用

item_tag

的itemId | tagId

回答

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等)来做。

+0

我还没有真正与意见。上述部分是需要在每个查询之前运行还是仅在创建连接时运行一次? – Helto 2013-03-23 22:14:55

+0

我真的很喜欢你的解决方案,并且你添加了对标题的搜索并给予不同领域的权重。如果您有机会,您是否愿意解释我可以如何修改这个以适应多种搜索条件?它们将以逗号分隔的字符串形式出现。 – Helto 2013-03-24 22:40:04

+0

@你好,你创建视图一次,然后你从他们的查询,就好像他们是普通表(!)。如果您需要更新您的视图,请运行: 'CREATE OR REPLACE VIEW AS '。 关于你的最后一个疑问,我会尽力帮助你(今天如果可能的话),当我有时间(让我们看看如果我能) – 2013-03-26 18:50:47

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不匹配的所有项目。

另一种选择是创建临时表。使用正确的名称为所有类别创建一个,使用正确名称的所有类别创建一个。你可以选择items WHERE items.id IN categories_table OR items.id IN tags_table

+0

我认为这将让我在正确的轨道上,但表item_tag只映射标签的物品,所以标签表格需要被加入,以及搜索编辑我的职务名称 – Helto 2013-03-23 03:28:11

+0

。现在应该是正确的。 – 2013-03-24 01:29:39

相关问题