Чтобы поддерживать полнотекстовую индексацию в Symfony2, я использую зеркальную таблицу MyISAM. Мы регулярно копируем наш производственный набор данных в эту таблицу и создаем SearchEntity, который отображает структуру таблицы и связан с реальными объектами. Таким образом, мы можем выполнять наши поисковые запросы в нашем SearchRepository (используя собственный конструктор операторов MATCH AGAINST) и извлекать найденные объекты, разрешая ассоциации.
Теперь, когда я выполняю doctrine:schema:update
, Doctrine2 не распознает (добавленные вручную) индексы на этой таблице и хочет их удалить. К сожалению, нет аннотации к советам, в которой говорится: "Но не оставляйте этот индекс без изменений!".
Я уже пытался обмануть Doctrine с помощью аннотации @Index
с теми же полями, что и в полнотекстовом индексе (prefixed ft_), а затем выполнить некоторый SQL вручную, чтобы заменить их моим индексом FT, но это также не срабатывает: когда первоначально была Doctrine создает таблицу с теми фиктивными индексами, которые она терпит неудачу, потому что длина ключа ключа больше 1000 байтов (что является жестким пределом по очевидным причинам в MySQL)
Вопрос: могу ли я посоветовать Доктрине оставить индексы, которые она находит в таблице, нетронутой в схеме: команда обновления? Есть ли способ взломать это в рамки? Крайне громоздко воссоздать индекс полного текста после каждого обновления схемы: (
SearchEntity:
/**
* @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 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;
SQL для создания индексов tmp_search (сначала отбросьте, какая учение останется там, а затем создайте наш)
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);