将类似关键字组合为一个关键字

时间:2013-11-11 14:53:20

标签: php mysql

表(market_items)的列(关键字)具有用逗号分隔每个关键字的关键字。我正在使用此查询来获取关键字;

$cid = intval($cid);
$query = $db->query("
    SELECT keywords
    FROM ".TABLE_PREFIX."market_items
    WHERE cid = '{$cid}'
    GROUP BY keywords
    ORDER BY dateline DESC
");
$cat_tags = '';
while ($t = $db->fetch_array($query))
{
    $keywords = trim($t['keywords']);
    $keys = explode(",",$keywords);
    foreach ($keys AS $key)
    {
        $cat_tags .= '<span class="small_buttons_class"><a href="market.php?action=tag_items&keywords='.$key.'">'.$key.'</a></span> ';
    }
}

它可以很好地获取关键字,但它显示类似的关键字:

keyword1 keyword2 keyword1 keyword3 keyword4 keyword5 keyword3

“注意上面的关键字编号”

如何删除相似的关键字并将其显示为此? e.g。

keyword1 keyword2 keyword3 keyword4 keyword5

为了说清楚,在“关键字”列中,关键字的存储方式如下:

keyword2keyword4keyword3keyword1

请帮忙!

5 个答案:

答案 0 :(得分:3)

您遇到了以逗号分隔的字符串存储列表的已知困难之一:确保列表中的列表唯一性或排序顺序。

请参阅我对Is storing a delimited list in a database column really that bad?的回答,了解此方法的更多陷阱。

要在SQL中解决此问题,您应该将关键字列表存储为非字符串,但在第二个表中每行存储一个关键字。

CREATE TABLE market_items_keywords (
  cid INT,
  keyword VARCHAR(20),
  PRIMARY KEY (cid, keyword)
);

定义此表中的主键,以便每个cid可以有多个关键字,但对于给定的cid,每个关键字只出现一次,并按字母顺序排列。

以这种方式存储关键字会带来很多其他好处。

  • 您可以将keyword列编入索引,以便比使用LIKE或正则表达式更有效地查找哪个cid具有给定关键字。
  • 您可以执行哪些关键字最受欢迎的报告。
  • 您可以轻松获取整个项目中使用的不同关键字列表。

重新评论:

您仍然可以使用一个查询来获取关键字,但保证列表是唯一且预先排序的:

$query = $db->query("
    SELECT keyword
    FROM ".TABLE_PREFIX."market_items_keywords
    WHERE cid = '{$cid}'
");

如果您需要按日期排序:

$query = $db->query("
    SELECT k.keyword
    FROM ".TABLE_PREFIX."market_items_keywords AS k
    JOIN ".TABLE_PREFIX."market_items AS i USING (cid)
    WHERE k.cid = '{$cid}'
    ORDER BY i.dateline DESC
");

这样做意味着您不必爆炸()关键字列表,也不需要在while循环中使用foreach循环。只需获取行。

答案 1 :(得分:1)

while ($t = $db->fetch_array($query))
{
    $keywords = trim($t['keywords']);
    $keys = explode(",",$keywords);
    foreach ($keys AS $key)
    {
        $tags[$key] = $key;        
    }
}
foreach ($tags as $tag) {
    $cat_tags .= '<span class="small_buttons_class"><a href="market.php?action=tag_items&keywords='.$tag.'">'.$tag.'</a></span> ';
}

答案 2 :(得分:1)

试试这个;

$cid = intval($cid);
$query = $db->query("
    SELECT keywords
    FROM ".TABLE_PREFIX."market_items
    WHERE cid = '{$cid}'
    ORDER BY dateline DESC
");
$cat_tags = '';
while ($t = $db->fetch_array($query))
{
    $keywords = trim($t['keywords']);
    $keys = explode(",",$keywords);
    $keys = array_unique($keys);
    foreach ($keys AS $key)
    {
        $key = trim($key);
        $key_collect[$key] = $key;
    }
}

foreach ($key_collect as $k)
{
    $cat_tags .= '<span class="small_buttons_class"><a href="market.php?action=tag_items&keywords='.$k.'">'.$k.'</a></span> ';
}

答案 3 :(得分:0)

SELECT DISTINCT ... {和你的查询的其余部分}

在我看来,你不需要“分组”

答案 4 :(得分:0)

Porter's algorithm。几年前我在西班牙语搜索引擎上做了一个实现。英语实现更容易。您可以从我的代码PHP Stemmer开始。这可以从基于语法规则的单词中删除语法后缀。