Я написал метод пользовательского поиска следующим образом:
public function findSubstanceListNotifications(Query $query, array $options)
{
$date_start = $options['date_start'];
$date_end = $options['date_end'];
$list_id = $options['list_id'];
$list_substances = TableRegistry::getTableLocator()->get('TblListsSubstances')->find()
->select('substance_id')->where(['list_id IN' => $list_id])->enableHydration(false);
if ($list_substances->isEmpty()) {
return false;
}
$query = $this->find()
->select(['RevisionSubstances.date', 'RevisionSubstances.comment', 'RevisionSubstances.id', 'Substances.name', 'Substances.app_id'])
->where(['substance_id IN' => array_column($list_substances->toArray(), 'substance_id')]);
$query->where(['RevisionSubstances.date >=' => $date_start, 'RevisionSubstances.date <=' => $date_end]);
$query->contain('Substances');
$query->order(['RevisionSubstances.date' => 'DESC', 'Substances.app_id' => 'ASC']);
$query->enableHydration(false);
if ($query->isEmpty()) {
return false;
}
return $query;
}
Я получаю фатальную ошибку PHP из-за превышения лимита памяти при выполнении этого.
Причина, я подозреваю, заключается в том, что условие substance_id IN
использует массив с несколькими тысячами ключей.
Есть ли альтернативный способ записи этого, где вместо IN
следует массивЯ мог бы написать оператор SELECT
на этом этапе? Подобно подзапросу в MySQL.
SQL для условия описывается $list_substances
, но по существу это:
SELECT substance_id FROM tbl_lists_substances WHERE list_id IN(1,2,3,4);
Приведенное выше условие IN()
использует идентификаторы, относящиеся к зарегистрированномув пользователя. Тем не менее, этот массив - самое большее - имеет менее 20 ключей, поэтому я не думаю, что здесь будут какие-либо подобные проблемы с памятью. Но мне нужно знать, как получить к ним доступ во время выполнения подзапроса.
CakePHP версия 3.7
Я читал об использовании newExpr()
в документах но не могу понять, как вставить оператор SELECT
на этом этапе так, чтобы он работал.