【发布时间】:2013-11-09 22:01:29
【问题描述】:
为了在 Symfony2 中支持全文索引,我使用了 MyISAM 镜像表。我们会定期将生产数据集复制到该表中,并创建一个 SearchEntity 来映射表的结构并与真实实体相关联。因此,我们可以在 SearchRepository 上执行搜索查询(使用自定义 MATCH AGAINST 语句构建器)并通过解析关联来检索找到的实体。
现在,当我执行 doctrine:schema:updateDoctrine2 时,它无法识别该表上的(手动添加的)索引并想要删除它们。不幸的是,没有建议注释说“但保持这个索引不变!”。
我已经尝试使用@Index 注释来欺骗 Doctrine,其字段与全文索引(前缀 ft_)中的字段相同,然后手动执行一些 SQL 以用我的 FT 索引替换它们,但同样失败:当 Doctrine 最初使用那些虚拟索引创建表失败,因为索引键长度大于 1000 字节(这是 MySQL 中明显原因的硬限制)
问题是:我可以建议 Doctrine 将它在表中找到的索引原封不动地保留在 schema:update 命令上吗?有没有办法将其破解到框架中?每次模式更新后重新创建全文索引非常麻烦:(
搜索实体:
/**
* @ORM\Table(name="tmp_search2",options={"engine"="MyISAM"},
* uniqueConstraints={@ORM\UniqueConstraint(name="uq",columns={"language_id","product_offer_id","product_group_id","retailer_id"} )},
* indexes={@Index(name="price_idx", columns={"product_offer_price"}),
* @Index(name="started_at_idx", columns={"product_offer_started_at"}),
* @Index(name="ended_at_idx", columns={"product_offer_ended_at"}),
* @Index(name="ft_products", columns={"product_name"}),
* @Index(name="ft_product_group", columns={"product_group_name"}),
* @Index(name="ft_product_retailer", columns={"retailer_name"})
* }
* )
* @ORM\Entity(repositoryClass="SearchRepository")
*/
class SearchEntity
{
/**
* This field is only here to satisfy doctrine's need for a non-composite primary key.
* @ORM\Id
* @ORM\Column(name="id", type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $searchId;
/**
* @ORM\ManyToOne(targetEntity="ProductOffer")
* @ORM\JoinColumn(name="product_offer_id", referencedColumnName="id")
*/
private $productOffer;
/**
* @var integer
*
* @ORM\Column(name="product_offer_price", type="integer")
*/
private $price;
创建 tmp_search 索引的 SQL(首先删除学说留下的内容,然后创建我们的)
DROP INDEX ft_products ON tmp_search2;
DROP INDEX ft_product_group ON tmp_search2;
DROP INDEX ft_product_retailer ON tmp_search2;
# import product data and then...
CREATE FULLTEXT INDEX ft_products ON tmp_search2 (product_name,product_short_text,product_long_text);
CREATE FULLTEXT INDEX ft_product_group ON tmp_search2 (product_group_name);
CREATE FULLTEXT INDEX ft_product_retailer ON tmp_search2 (retailer_name);
【问题讨论】:
-
这不是直接的解决方案,但您可以创建自己的控制台命令,该命令在内部执行
doctrine:schema:update,然后运行您的自定义 SQL 以创建附加索引 -
所以我永远不会再执行教义:模式:更新自身?不,我认为它属于框架并且在那里很好(每个人都知道它应该如何工作:如果它说,一切都很好,一切都很好)。我认为 Doctrine 方面需要做一些工作来真正解决这个问题。但也许有一些方法可以扩展 Doctrine 的类型(最好使用包),以便正确识别全文索引
-
在 Doctrine 2.5 中有一个“标志”选项。设置为“全文”,它将能够自动创建 ft 索引:stackoverflow.com/questions/23448266/…
标签: php mysql sql symfony doctrine-orm