Doctrine2 - используйте полный текст и MyIsam - PullRequest
7 голосов
/ 30 августа 2011

Я создаю приложение в Symfony2, используя Doctrine2 с mysql.Я хотел бы использовать полнотекстовый поиск.Я не могу найти много о том, как реализовать это - сейчас я застрял на том, как установить движок таблицы на myisam.

Кажется, что невозможно установить тип таблицы с помощью аннотаций.Кроме того, если я сделал это вручную, выполнив запрос «ALTER TABLE», я не уверен, что Doctrine2 продолжит работать должным образом - зависит ли это от внешних ключей InnoDB?

Есть ли лучшее место длязадать эти вопросы?

Ответы [ 2 ]

15 голосов
/ 03 мая 2012

ВВЕДЕНИЕ

Doctrine2 использует InnoDB, который поддерживает внешние ключи, используемые в ассоциациях Doctrine.Но так как MyISAM пока не поддерживает это, вы не можете использовать MyISAM для управления объектами Doctrine.

С другой стороны, MySQL v5.6, находящийся в стадии разработки, принесет поддержку InnoDB FTS и, таким образом, включитПолнотекстовый поиск в таблицах InnoDB.

РЕШЕНИЯ

Таким образом, есть два решения:

  1. Использование MySQL v5.6 на свой страх и риски взломав немного Doctrine для реализации метода MATCH AGAINST: ссылка на французском ... (я мог бы перевести, если нужно, но все еще есть ошибки, и я бы не рекомендовал это решение)

  2. Как описано в quickshifti, создание таблицы MyISAM с полнотекстовым индексом просто для выполнения поиска.Как Doctrine2 разрешает собственные запросы SQL и как вы можете сопоставить этот запрос с сущностью ( подробности здесь ).

ПРИМЕР ДЛЯ 2-го РЕШЕНИЯ

Рассмотрим следующие таблицы:

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 должен остатьсядо настоящего времени.Вместо использования задачи cron вы можете добавить триггеры (INSERT, UPDATE и DELETE) следующим образом:

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.

0 голосов
/ 19 октября 2011

Doctrine отказалась от полнотекстовой функции поиска с v1 при переходе к Doctrine2.Скорее всего, вам придется отказаться от собственной поддержки полнотекстового поиска в Doctrine2.

Я подумываю об использовании миграций для создания самих таблиц, выполнении поисковых запросов с опцией собственного запроса SQL для получения наборов идентификаторовкоторые ссылаются на таблицы, управляемые Doctrine, а затем используют упомянутые наборы идентификаторов для нормального увлажнения записей через Doctrine.

Вероятно, что-то периодическое будет обновлять полнотекстовые таблицы.

...