Я работаю над приложением в CakePHP 3.7.
У нас есть 3 таблицы базы данных со следующей иерархией.Эти таблицы связаны правильно в соответствии с классами таблиц:
(Ассоциации показаны в предыдущем вопросе: CakePHP 3 - ассоциация не определена - даже если она выглядит как )
Iможно получить все данные из всех трех таблиц следующим образом:
$regulations = TableRegistry::getTableLocator()->get('Regulations');
$data = $regulations->find('all', ['contain' => ['Groups' => ['Filters']]]);
$data = $data->toArray();
Таблица filters
содержит> 1300 записей.Поэтому я пытаюсь создать функцию, которая постепенно загружает данные через вызовы AJAX, когда пользователь прокручивает страницу вниз, как описано здесь: https://makitweb.com/load-content-on-page-scroll-with-jquery-and-ajax/
Проблема в том, что мне нужно иметь возможность считатьобщее количество возвращенных строк.Однако данные для этого существуют в 3 таблицах.
Если я сделаю debug($data->count());
, он выдаст 8, потому что в таблице regulations
есть 8 строк.В идеале мне нужно количество строк, которые он возвращает в таблице filters
(~ 1300 строк), где большая часть данных существует с точки зрения начальной загрузки.
Проблема еще более усложняется, потому что эта функцияпозволяет пользователю выполнять поиск.Может случиться так, что данный поисковый термин существует во всех 3 таблицах, 1 - 2 из таблиц, или не существует вообще.Я не знаю, является ли правильный способ сделать это, чтобы попытаться подсчитать строки, возвращаемые в каждой таблице, или строки в целом?
Я прочитал Как разбить на страницы связанные записи? и Фильтрация по связанным данным в Cake docs.
Дополнительная информация
Проблема, похоже, сводится к тому, как написать запрос с использованием синтаксиса ORM, предоставляемого Cake.Следующий (обычный MySQL) запрос на самом деле сделает то, что я хочу.Предполагая, что пользователь искал «Асбест»:
SELECT
regulations.label AS regulations_label,
groups.label AS groups_label,
filters.label AS filters_label
FROM
groups
JOIN regulations
ON groups.regulation_id = regulations.id
JOIN filters
ON filters.group_id = groups.id
WHERE regulations.label LIKE '%Asbestos%'
OR groups.label LIKE '%Asbestos%'
OR filters.label LIKE '%Asbestos%'
ORDER BY
regulations.id ASC,
groups_label ASC,
filters_label ASC
LIMIT 0,50
Допустим, возвращено 203 строки.Условие LIMIT
означает, что я получаю первые 50. Некоторые js на внешнем интерфейсе (что не очень важно с точки зрения его работы) будут выполнять вызов ajax, когда пользователь прокручивает страницу вниз, чтобы сновазапустите этот запрос с другим пределом (например, LIMIT 51, 100
для следующего набора результатов).
Проблема, кажется, в два раза:
Если я напишузапрос с использованием синтаксиса Cake ORM, вывод представляет собой вложенный массив.И наоборот, если я пишу это на простом SQL, он возвращает таблицу, которая содержит всего 3 столбца с метками, которые мне нужно отобразить.С этой структурой намного проще работать с точки зрения вывода необходимых данных на странице.
Второй - и, возможно, более важный вопрос - это то, что я не вижу, как можно написать условие LIMIT
в синтаксисе ORM, чтобы сделать этоработать из-за вложенной структуры, описанной в 1. Если я, например, добавил $data->limit(50)
, это только накладывает это ограничение на таблицу regulations
.По сути, поиск работает для любых связанных данных в первых 50 строках в regulations
.В отличие от условия LIMIT
, которое я написал в MySQL, в котором учитывался бы весь набор результатов, включающий столбцы из всех трех таблиц.
Для дальнейшей проработки пункта 2,Предположим, что таблицы содержат следующие номера строк:
regulations
: 150 groups
: 1000 filters
: 5000
Если я использую $data->limit(50)
, это будет применяться только к 50 строкам в таблице regulations
.Мне нужно применить LIMIT
набор результатов после поиска всех строк во всех 3 таблицах для данного термина.