PHP / SQL-使用`LIKE`和`MATCH AGAINST`搜索数据库

时间:2019-04-26 08:45:23

标签: php mysql sql full-text-search

我在数据库中有一个名为pro_search的表,已在其中翻译了不同语言的不同产品的元信息。

我的表结构如下:id pro_id en de es fr it nl pl pt 其中pro_id是产品的ID,其他列中的两个字母代码代表该产品元数据的翻译语言。

我运行以下代码在数据库上创建FULLTEXT索引:

ALTER TABLE pro_search ADD FULLTEXT INDEX `FullText` (`en` ASC, `de` ASC, `es` ASC, `fr` ASC, `it` ASC, `nl` ASC, `pl` ASC, `pt` ASC);
ALTER TABLE pro_search ADD FULLTEXT INDEX `enFullText` (`en` ASC);
ALTER TABLE pro_search ADD FULLTEXT INDEX `deFullText` (`de` ASC);
ALTER TABLE pro_search ADD FULLTEXT INDEX `esFullText` (`es` ASC);
ALTER TABLE pro_search ADD FULLTEXT INDEX `frFullText` (`fr` ASC);
ALTER TABLE pro_search ADD FULLTEXT INDEX `itFullText` (`it` ASC);
ALTER TABLE pro_search ADD FULLTEXT INDEX `nlFullText` (`nl` ASC);
ALTER TABLE pro_search ADD FULLTEXT INDEX `plFullText` (`pl` ASC);
ALTER TABLE pro_search ADD FULLTEXT INDEX `ptFullText` (`pt` ASC);

enter image description here

然后,我尝试进行一些测试以查看返回的结果:

$lang = 'en';
$term = 'this is a test';

$params = [$term];
$sql = "SELECT * FROM pro_search WHERE $lang=?;";
$stmt = DB::run($sql,$params);
$count = $stmt->rowCount();
echo $count.'<br />';
// returns '1' so there is definitely a match

$params = ['%'.$term.'%'];
$sql = "SELECT * FROM pro_search WHERE $lang LIKE '?';";
$stmt = DB::run($sql,$params);
$count = $stmt->rowCount();
echo $count.'<br />';
// returns '0'

$params = [$term];
$sql = "SELECT * FROM pro_search WHERE MATCH ($lang) AGAINST ('?');";
$stmt = DB::run($sql,$params);
$count = $stmt->rowCount();
echo $count.'<br />';
// returns '0'

$params = [$term];
$sql = "SELECT * FROM pro_search WHERE MATCH ($lang) AGAINST ('?' IN NATURAL LANGUAGE MODE);";
$stmt = DB::run($sql,$params);
$count = $stmt->rowCount();
echo $count.'<br />';
// returns '0'

$params = [$term];
$sql = "SELECT * FROM pro_search WHERE MATCH ($lang) AGAINST ('?' WITH QUERY EXPANSION);";
$stmt = DB::run($sql,$params);
$count = $stmt->rowCount();
echo $count.'<br />';
// returns '0'

$params = [$term];
$sql = "SELECT * FROM pro_search WHERE MATCH ($lang) AGAINST ('?' IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION);";
$stmt = DB::run($sql,$params);
$count = $stmt->rowCount();
echo $count.'<br />';
// returns '0'

如您所见,第一个精确查询返回一个结果,如果我直接在SELECT * FROM pro_search WHERE en LIKE '%test%'的phpMyAdmin中进行查询,我将得到7个结果,但是在我的php文件中的第二个查询中却没有结果。一样。

我在这里错过了什么吗?我认为所有这些都应该至少返回一个结果。

// -----编辑----- //

这是我为表格创建代码的地方,以防万一:

CREATE TABLE `pro_search` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `pro_id` int(11) NOT NULL,
 `en` varchar(255) DEFAULT NULL,
 `de` varchar(255) DEFAULT NULL,
 `es` varchar(255) DEFAULT NULL,
 `fr` varchar(255) DEFAULT NULL,
 `it` varchar(255) DEFAULT NULL,
 `nl` varchar(255) DEFAULT NULL,
 `pl` varchar(255) DEFAULT NULL,
 `pt` varchar(255) DEFAULT NULL,
 PRIMARY KEY (`id`),
 FULLTEXT KEY `FullText` (`en`,`de`,`es`,`fr`,`it`,`nl`,`pl`,`pt`),
 FULLTEXT KEY `enFullText` (`en`),
 FULLTEXT KEY `deFullText` (`de`),
 FULLTEXT KEY `esFullText` (`es`),
 FULLTEXT KEY `frFullText` (`fr`),
 FULLTEXT KEY `itFullText` (`it`),
 FULLTEXT KEY `nlFullText` (`nl`),
 FULLTEXT KEY `plFullText` (`pl`),
 FULLTEXT KEY `ptFullText` (`pt`)
) ENGINE=MyISAM AUTO_INCREMENT=1597 DEFAULT CHARSET=latin1

此外,人们会如何建议使用多种语言进行搜索?我以这种方式设置了产品meta的翻译,但是我们没有翻译器,因此其中一些是直接从Google翻译中进行的,只是在此进行了一些更改。但是,如果我能正常工作,我可能会尝试直接从包含产品标题,描述和元数据的产品表中创建索引。

我的看法有两种选择:

  1. 存储产品翻译并进行搜索,或者
  2. 翻译搜索词并用英语搜索

无论哪种方式,我们都可能会处理不良的Google翻译。

3 个答案:

答案 0 :(得分:1)

尝试移走您周围的'

  $params = ['%'.$term.'%'];
  $sql = "SELECT * FROM pro_search WHERE $lang LIKE ?;";
  $stmt = DB::run($sql,$params);
  $count = $stmt->rowCount();
  echo $count.'<br />';

在第一条语句中,您要添加不带引号的字符串参数:$lang=?。这意味着您不需要为其他语句在?周围加上单引号;

答案 1 :(得分:1)

只有第一个查询没有引号。

因此,DB :: run在添加引号。

从所有MATCH ...反对查询中删除报价。

这样,他们应该可以全部工作。

编辑: 试试这个

$params = [$term];
$sql = "SELECT * FROM pro_search WHERE MATCH ($lang) AGAINST (?);";
$stmt = DB::run($sql,$params);
$count = $stmt->rowCount();
echo $count.'<br />';

答案 2 :(得分:0)

我假设<Location /version1/> ProxyPass http://some.ip.address:3003/ retry=0 timeout=60 keepalive=On ProxyPassReverse http://some.ip.address:3003/ </Location> <Location /version2/> ProxyPass http://some.another.ip.address:3004/ retry=0 timeout=60 keepalive=On ProxyPassReverse http://some.another.ip.address:3004/ </Location> <Location /> Order Allow, Deny </Location> 在字符串中加上引号吗?如果是这样,它将创建

DB::run($sql,$params);

删除报价。