Doctrine2 - 使用全文和MyIsam

Sti*_*ing 7 myisam full-text-search doctrine-orm

我正在Symfony2中构建一个应用程序,使用Doctrine2和mysql.我想使用全文搜索.我找不到如何实现这一点 - 现在我仍然坚持如何将表引擎设置为myisam.

似乎无法使用注释设置表类型.另外,如果我通过运行"ALTER TABLE"查询手动完成,我不确定Doctrine2是否会继续正常工作 - 它是否依赖于InnoDB外键?

有没有更好的地方提出这些问题?

max*_*dec 15

介绍

Doctrine2使用InnoDB,它支持Doctrine关联中使用的外键.但由于MyISAM尚未支持此功能,因此您无法使用MyISAM来管理Doctrine实体.

另一方面,目前正在开发的MySQL v5.6将带来InnoDB FTS的支持,因此将启用InnoDB表中的全文搜索.

解决方案

所以有两种解决方案:

  1. 使用MySQL v5.6需要您自担风险,并且有点教条实施MATCH AGAINST方法:链接法语...(如果需要我可以翻译,但仍然有错误,我不推荐这个解决方案)

  2. 如quickshifti所述,创建一个带有全文索引的MyISAM表只是为了执行搜索.由于Doctrine2允许本机SQL请求,因此您可以将此请求映射到实体(详情请参见此处).

第二个解决方案的示例

请考虑以下表格:

table 'user' : InnoDB [id, name, email]
table 'search_user : MyISAM [user_id, name -> FULLTEXT]
Run Code Online (Sandbox Code Playgroud)

然后你只需要编写一个带有JOIN和映射的搜索请求(在存储库中):

<?php

public function searchUser($string) {

    // 1. Mapping
    $rsm = new ResultSetMapping();
    $rsm->addEntityResult('Acme\DefaultBundle\Entity\User', 'u');
    $rsm->addFieldResult('u', 'id', 'id');
    $rsm->addFieldResult('u', 'name', 'name');
    $rsm->addFieldResult('u', 'email', 'email');

    // 2. Native SQL
    $sql = 'SELECT u.id, u.name FROM search_user AS s JOIN user AS u ON s.user_id = u.id  WHERE MATCH(s.name) AGAINST($string IN BOOLEAN MODE)> 0;

    // 3. Run the query
    $query = $this->_em->createNativeQuery($sql, $rsm);

    // 4. Get the results as Entities !
    $results = $query->getResult();

    return $results;
}
?>
Run Code Online (Sandbox Code Playgroud)

但FULLTEXT指数需要保持最新状态.您可以添加触发器(INSERT,UPDATE和DELETE),而不是使用cron任务,如下所示:

CREATE TRIGGER trigger_insert_search_user
AFTER INSERT ON user
FOR EACH ROW
INSERT INTO search_user SET user_id=NEW.id, name=NEW.name;

CREATE TRIGGER trigger_update_search_user
AFTER UPDATE ON user
FOR EACH ROW
UPDATE search_user SET name=name WHERE user_id=OLD.id;

CREATE TRIGGER trigger_delete_search_user
AFTER DELETE ON user
FOR EACH ROW
DELETE FROM search_user WHERE user_id=OLD.id;
Run Code Online (Sandbox Code Playgroud)

这样您的search_user表将始终获得最后的更改.

当然,这只是一个例子,我想保持简单,我知道这个查询可以用LIKE完成.

  • 看起来不错.我实际上最终坚持使用Innodb并实施Sphinx,它运作良好:http://sphinxsearch.com/ (2认同)