Использование Memcached для кэширования результатов из Model::find()

Я хотел бы сохранить DocumentSet, возвращенный из Model::find(), в memcached. Однако я получаю MongoException ниже, когда пытаюсь работать с результатами после их извлечения из кеша. В частности, при использовании foreach исключение возникает при вызове if ($this->_resource->hasNext()) в строке 63 файла \data\source\mongo_db\Result.php.

Исключение Монго

Объект MongoCursor не был правильно инициализирован его конструктором

Я могу понять, почему это так.

Мой вопрос в том, есть ли способ предварительно заполнить Model::find() или создать свой собственный DocumentSet, чтобы я мог работать с данными? Обычно я просто преобразовывал его в массив и сохранял в кеше. Однако мне нужен доступ к некоторым написанным мной методам модели (например, Customer::fullName()).

Обновление: я нашел небольшое обходное решение, которое нормально, но не очень хорошо. Я сохраняю результаты Model::find() в виде массива в кеше $result->to('array'). Затем, после извлечения, я перебираю $results и заполняю новый массив Model::create($result, array("exists" => true) для каждого $result;


person Eric C    schedule 05.09.2012    source источник


Ответы (1)


DocumentSet, возвращаемый Model::find, содержит курсор Mongo db. Он не загружает все данные из базы данных до тех пор, пока элементы не будут итерированы. По мере повторения каждого элемента создается Document, который кэшируется в памяти в объекте DocumentSet. Встроенная функция php iterator_to_array() может использоваться для преобразования DocumentSet в массив документов, которые вы можете кэшировать.

Как вы упомянули в своем обновлении, вы также можете использовать ->to('array') для подготовки к кэшированию, а затем Model::create() для его резервного копирования. Одно предостережение относительно этого метода: когда вы используете ->to('array'), он также преобразует объекты MongoId и MongoDate в строки и целые числа соответственно. Если вы определили $_schema для своей модели и установили типы 'id' и 'date', они будут возвращены к исходным объектам MongoId и MongoDate в документе, возвращенном Model::create(). Если у вас нет схемы для всех ваших полей, это может быть проблемой. У меня есть недавний запрос на вытягивание, который пытается сделать возможным выполнение ->to('array') без приведения нативного объекты монго (также устраняет проблему с объектами монго, которые всегда преобразуются внутри массивов вложенных документов).

FWIW, я на самом деле предпочитаю сохранять только данные в кеше, потому что это меньше места, чем сериализация всего php-объекта, и позволяет избежать потенциальных проблем с не определенными классами или другими элементами, не инициализированными при извлечении элемента из кеша.

Я не пробовал это ... но я думаю, вы могли бы создать класс стратегии кэширования, который позаботился бы об этом прозрачно для вас. Еще один пример большой заботы, которая была приложена к тому, чтобы сделать Lithium очень гибкой и мощной структурой. http://li3.me/docs/lithium/storage/cache/strategy

person rmarscher    schedule 09.09.2012
comment
Мне нравится ваша идея с индивидуальной стратегией. В настоящее время я полагаюсь на $_schema для правильного приведения типов. - person Eric C; 10.09.2012