单独的主题标签和文本PHP

时间:2014-10-15 12:25:05

标签: php mysql preg-replace hashtag

My database

嗨,这是我的桌子的一个例子,我希望能够像这样搜索:#mat#godis并且能够获得具有这些标签的2个结果(ID 5和ID 7)

这是我的PHP代码到目前为止它在搜索示例(Globen),(Globen #mat)和(#mat)

时有效
//Strip Search
function selectSearch($search){
$lol = preg_replace('/(^|\s)#(\w*[a-zA-Z_]+\w*)/'," ",$search);
$keywords = explode(" ", preg_replace("/\s+/", " ", $lol));
foreach($keywords as $keyword){
 $wherelike[] = "name LIKE '%$keyword%'";
}
$search = implode(" and ", $wherelike);
return $search;
}

//Strip tags
function selectTags($tags){
$str = $tags;
    $bits = explode(' ', $str);
    $newquery = array();

    foreach($bits as $bit){
        if(strlen($bit) > 0 && $bit[0] === '#') $newquery[] = $bit;
    }

    $newquery = implode('', $newquery);

    $keywords = explode(" ", preg_replace("/\s+/", " ", $newquery));
    foreach($keywords as $keyword){
        $wherelike[] = "tags LIKE '%".ltrim($keyword,'#')."%'";
    }
    $tags = implode(" or ", $wherelike);    

    return $tags;
} 

返回(搜索#mat#godis)

select * from stores where name LIKE '%%' and name LIKE '%#godis%' and tags LIKE '%mat#godis%'order by id desc limit 8

我希望查询是这样的

select * from stores where name LIKE '%%'and tags LIKE '%mat%' and tags LIKE '%godis%' order by id desc limit 8

2 个答案:

答案 0 :(得分:2)

这个设计非常糟糕。您需要使用关系表。问题是,如果您尝试搜索%#mat%,那么,如果有#matheus这样的标记,那也会给您带来结果。

当然,这种情况有解决办法,但这太复杂了。

我不明白这是什么:name LIKE '%%'

所以你需要的是创建表格,正如ChrisForrence所提到的,这样称为store_tag

CREATE TABLE IF NOT EXISTS `store_tag` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`tag` varchar(255) NOT NULL COMMENT 'Tag like #mat',
`user_id` int(11) NOT NULL COMMENT 'The foreign ID',
 PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

在此之后,您需要编写一个小脚本,原始表中所有记录的循环是什么,获取id和标记,爆炸标记,将其单独插入新表{{1} }。

然后,使用:

store_tag

(上面的查询未经过测试,仅作为示例,当然您不需要SELECT * FROM store_tag, orig_table INNER JOIN origTable ON origTable.id = store_tag.user_id WHERE tag = '#mat' OR tag = '#godis')。

这将为您提供所需的结果。

维护数据要容易得多。

当然,这个创建者可以从现有数据库中备份。

答案 1 :(得分:1)

正如我在评论中提到的,我会为标签创建一个单独的表格,如:

# The original table. Notice the lack of a 'tags' column
CREATE TABLE `stores` (
  `id` INTEGER UNSIGNED AUTO_INCREMENT,
  `name` VARCHAR(64) UNIQUE,
  PRIMARY KEY(`id`)
);

# A new table, relating stores to tags
CREATE TABLE `store_tags` (
  `store_id` INTEGER UNSIGNED,
  `label` VARCHAR(64),
  PRIMARY KEY(`store_id`, `label`),
  FOREIGN KEY(`store_id`) REFERENCES `stores`(`id`) ON DELETE CASCADE
);

从这里,您可以使用以下查询的变体来检查与所有标记匹配的商店:

SELECT * FROM `stores` 
    WHERE `id` IN (SELECT `store_id` FROM `store_tags` WHERE `label`='mat') 
      AND `id` IN (SELECT `store_id` FROM `store_tags` WHERE `label`='godis')
    ORDER BY `id` DESC LIMIT 8

您可以使用它将标记拆分为正确的WHERE子句,以及用作PDO查询的输入参数的标记数组

/* Returns an array containing the WHERE clauses, along 
 * with the tags themselves (used to populate the input parameters for PDO)
 */
function searchTags($in) {
  $rQ = '';

  // Filter out empty array input elements
  $tags = array_filter(explode('#', $in));
  if(!count($tags)) {
    return false;
  }

  $first = true;
  foreach($tags as $tag) {
    $rQ .= ($first ? ' WHERE' : ' AND') . ' `id` IN (SELECT `store_id` FROM `store_tags` WHERE `label`=?)';
    if($first) $first = false;
  }
  return array($rQ, $tags);

}