Doctrine2 - 使用全文和MyIsam

时间:2011-08-30 15:50:45

标签: doctrine-orm myisam full-text-search

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

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

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

2 个答案:

答案 0 :(得分:15)

引言

Doctrine2使用InnoDB,它支持Doctrine关联中使用的外键。但由于MyISAM尚不支持,您无法使用MyISAM来管理Doctrine实体。

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

所以有两种解决方案:

  1. 使用MySQL v5.6需要您自担风险,并且有点教条实施MATCH AGAINST方法:link in french...(如果需要,我可以翻译,但仍然存在错误,我不建议这样做溶液)

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

  3. 第二解决方案的示例

    考虑以下表格:

    table 'user' : InnoDB [id, name, email]
    table 'search_user : MyISAM [user_id, name -> FULLTEXT]
    

    然后你只需要用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;
    }
    ?>
    

    但是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;
    

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

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

答案 1 :(得分:0)

Doctrine在转移到Doctrine2时从v1中删除了全文可搜索功能。您可能需要在Doctrine2中进行全文搜索。

我正在考虑使用迁移来自己生成表,使用本机SQL查询选项运行搜索查询,以获取引用由Doctrine管理的表的ID集,然后使用所述id组通常通过水合记录教义。

可能会定期更新全文表格。