嗨,这是我的桌子的一个例子,我希望能够像这样搜索:#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
答案 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);
}