CakePHP 3 - использование IN ... SELECT в пользовательском поиске - PullRequest
1 голос
/ 01 октября 2019

Я написал метод пользовательского поиска следующим образом:

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 на этом этапе так, чтобы он работал.

1 Ответ

0 голосов
/ 01 октября 2019

Несколько тысяч ключей может быть слишком много. Я не уверен, каковы ваши проблемы с подзапросом, но он должен работать просто отлично, просто передайте $list_substances в качестве условия, например:

->where(['substance_id IN' => $list_substances])
...