nepster-web
@nepster-web

Есть ли удобное решение для сложных запросов?

Работая с Doctrine2 я заметил, что с ее помощью очень удобно сохранять данные сущностей, однако с выборками нужно существенно повозиться. Понятно, что это не проблема самой ORM, а скорее вопрос подходов, и все-же хочется найти удобное решение для формирования универсальных и сложных запросов.

Итак, пример будет как всегда самый простой: есть записи, теги к ним, картинки и автор.
Задача тоже простая: получить список категорий.

И по мимо этого есть еще список определенных кейсов по оптимизации и фильтрации:
- Список записей
- Список записей с картинками
- Список записей с тегами
- Список записей с картинками и тегами
- Список записей с картинками, тегами и автором
- Список записей с картинками и тегами, где автор такой-то
- Список записей с картинками и тегами, где автор такой-то и тег такой-то
- Список записей где количество тегов больше 5, а рейтинг автора меньше 100 при условии, в в записи больше 1 картинки.

По сути это все упирается в 1 запрос, "получения списка записей", с фильтрацией и условиями.
Однако реализовать подобное с помощью doctrine2 да и наверное голом SQL с PHP достаточно кодообъемно.

На всякий случай я приведу сюда пример решения от которого я отказался сразу. Это отдельный метод для каждого запроса, например:
$this->recordRepository->findList($first, $offset);
$this->recordRepository->findListWithTags($first, $offset);
$this->recordRepository->findListWithTagsAndImages($first, $offset);
$this->recordRepository->findListWithTagsAndImagesAndAuthor($first, $offset);
$this->recordRepository->findListWithTagsAndImagesAndAuthor($first, $offset);
$this->recordRepository->findListWithTagsAndImagesAndAuthorByAuthor($first, $offset, $userId);
$this->recordRepository->findListWithTagsAndImagesAndAuthorByAuthorAndTag($first, $offset, $userId, $tagId);
...

В общем таких комбинаций одного запроса может быть весьма много. В качестве преимущества можно рассмотреть удобство тестирования, но вот недостатки весьма перекрывают это дело:
- например findListWithTags и findListWithTagsAndImages не несут в себе ничего для бизнес логики, а только внутреннюю оптимизацию.
- очень сильно разрастается кол-во методов в репозитории
- появляется некая грязь по коду, с теми-же условиями но внутри.

Пока мое решение, что-то вроде:
$this->recordRepository->findListByCondition($condition);


Где $condition, некий объект собирающий у себя условия. Этот подход выглядит весьма рабочий, однако имеет ряд недостатков:
- Когда мы заполняем $condition нашими условиями, существует возможность дублирования в неких кейсах.
- В репозитории нужно проанализировать $condition, в результате появляется множество условий
- Сложность тестирования.

В общем хотелось бы получить совет или наводку на решение данного вопроса.
  • Вопрос задан
  • 283 просмотра
Решения вопроса 1
в качестве возможной наводки могу подкинуть rikbruil/doctrine-specification happyr/doctrine-specification
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы