MySQL全文搜索不起作用

时间:2014-05-22 15:30:49

标签: php mysql search

我有一个MySQL表格,如下所示:

$sql = "CREATE TABLE test(
id INT NOT NULL,
title VARCHAR(512) NOT NULL COLLATE utf8_general_ci,
body TEXT NOT NULL COLLATE utf8_general_ci,
dateStored VARCHAR(32) NOT NULL COLLATE utf8_general_ci,
fileName VARCHAR(128) NOT NULL COLLATE utf8_general_ci,

FOREIGN KEY(id) REFERENCES `database`.`parent`(id)

);";

我的存储引擎是MYISAM。

现在,当我想使用 body - MATCH AGAINST字段中搜索时,没有结果......

这是我的尝试:

$sql2 = "SELECT * FROM database.test 
        WHERE MATCH(body) AGAINST('?')";
$prepare = $pdo->prepare($sql2);
$prepare->execute( array( $pattern ) );
$fetch = $prepare->fetchAll();

这似乎很基本,但我的代码仍然不起作用。你能告诉我我的代码有什么问题吗?

这是因为我有一个引用另一个表的字段吗?

4 个答案:

答案 0 :(得分:3)

添加更多数据。默认情况下,MySQL会忽略表中50%或更多行中的任何单词,因为它认为这是一个“噪音”单词。

如果表中的行数非常少,通常会经常达到这个50%的限制(即如果你有两行,那么每个单词至少占行数的50%!)。

答案 1 :(得分:3)

我认为你错过了你所在领域的FULLTEXT索引。您需要在列上have a FULLTEXT index进行MATCH AGAINST次搜索。

使用表声明FULLTEXT索引或更改当前表以包含索引。

ALTER TABLE `test` ADD FULLTEXT (`body`)

另外,正如其他一些人所说的那样,单词长度有一个截止,而且还有50%的阈值会阻止结果出现。

答案 2 :(得分:1)

对于MySQL版本5.6 +

您只需添加FULLTEXT INDEX更改表格like Crackertastic described或直接在CREATE TABLE语句中定义。

这是一个有效的例子:

-- DROP TABLE child;
-- DROP TABLE parent;

CREATE TABLE parent (
    id INT NOT NULL,
    PRIMARY KEY (id)
) ENGINE=InnoDB; -- or MyISAM
CREATE TABLE child(
    id INT NOT NULL,
    title VARCHAR(512) NOT NULL COLLATE utf8_general_ci,
    body TEXT NOT NULL COLLATE utf8_general_ci,
    date_stored VARCHAR(32) NOT NULL COLLATE utf8_general_ci,
    file_name VARCHAR(128) NOT NULL COLLATE utf8_general_ci,
    parent_id INT NOT NULL,

    PRIMARY KEY (id),
    FOREIGN KEY (parent_id) REFERENCES parent(id),
    FULLTEXT (body)
) ENGINE=InnoDB; -- or MyISAM

INSERT INTO child (id, title, body, date_stored, file_name, parent_id) VALUES('1','test title 1','test body 1','22.05.2014','file1.txt',5);
INSERT INTO child (id, title, body, date_stored, file_name, parent_id) VALUES('2','asd','qwer','31.07.2019','yxcv.txt',6);
INSERT INTO child (id, title, body, date_stored, file_name, parent_id) VALUES('3','gfdsa','trewq','21.04.2015','hjkl.txt',7);

SELECT
    *
FROM
    child
WHERE
    MATCH(body) AGAINST('qwer')
;

SELECT请求返回带有id = 2的条目。


对于较旧的MySQL版本

在MySQL中,早于5.6的ves ves无法在FULLTEXT INDEX表上定义InnoDB

来自MySQL 5.5 docu

  

全文索引只能用于MyISAM个表。 (在MySQL 5.6及更高版本中,它们也可以与InnoDB表一起使用。)

因此,必须决定使用FOREIGN KEYFULLTEXT INDEX并选择存储引擎 - InnoDBMyISAM。由于InnoDB支持FOREIGN KEY限制,但不支持FULLTEXT索引。

尝试在FULLTEXT INDEX

上创建InnoDB
-- DROP TABLE child;
-- DROP TABLE parent;

CREATE TABLE parent (
    id INT NOT NULL,
    PRIMARY KEY (id)
) ENGINE=InnoDB;
CREATE TABLE child(
    id INT NOT NULL,
    title VARCHAR(512) NOT NULL COLLATE utf8_general_ci,
    body TEXT NOT NULL COLLATE utf8_general_ci,
    date_stored VARCHAR(32) NOT NULL COLLATE utf8_general_ci,
    file_name VARCHAR(128) NOT NULL COLLATE utf8_general_ci,
    parent_id INT NOT NULL,

    PRIMARY KEY (id),
    FOREIGN KEY (parent_id) REFERENCES parent(id)
) ENGINE=InnoDB;

ALTER TABLE `child` ADD FULLTEXT (`body`);

因错误而失败:

Query: ALTER TABLE `child` ADD FULLTEXT (`body`)

Error Code: 1214
The used table type doesn't support FULLTEXT indexes

因此,您必须将MyISAM用于FULLTEXT INDEX。然后,您只需添加FULLTEXT INDEX更改表like Crackertastic described或直接在CREATE TABLE语句中定义。

这是一个有效的例子:

-- DROP TABLE child;
-- DROP TABLE parent;

CREATE TABLE parent (
    id INT NOT NULL,
    PRIMARY KEY (id)
) ENGINE=MyISAM;
CREATE TABLE child(
    id INT NOT NULL,
    title VARCHAR(512) NOT NULL COLLATE utf8_general_ci,
    body TEXT NOT NULL COLLATE utf8_general_ci,
    date_stored VARCHAR(32) NOT NULL COLLATE utf8_general_ci,
    file_name VARCHAR(128) NOT NULL COLLATE utf8_general_ci,
    parent_id INT NOT NULL,

    PRIMARY KEY (id),
    FULLTEXT (body)
) ENGINE=MyISAM;

INSERT INTO child (id, title, body, date_stored, file_name, parent_id) VALUES('1','test title 1','test body 1','22.05.2014','file1.txt',5);
INSERT INTO child (id, title, body, date_stored, file_name, parent_id) VALUES('2','asd','qwer','31.07.2019','yxcv.txt',6);
INSERT INTO child (id, title, body, date_stored, file_name, parent_id) VALUES('3','gfdsa','trewq','21.04.2015','hjkl.txt',7);

SELECT
    *
FROM
    child
WHERE
    MATCH(body) AGAINST('qwer')
;

SELECT请求返回带有id = 2的条目。

答案 3 :(得分:1)

尝试IN BOOLEAN MODE。这不会忽略任何行。

http://dev.mysql.com/doc/refman/5.6/en/fulltext-boolean.html