我想在memcached中存储从Model :: find()返回的DocumentSet。但是,当我从缓存中检索结果后尝试处理结果时,我得到下面的MongoException。具体来说,使用foreach时,在\ data \ source \ mongo_db \ Result.php的第63行调用if ($this->_resource->hasNext())
时会抛出异常
MongoException
MongoCursor对象尚未被其构造函数
正确初始化
我能理解为什么会这样。
我的问题是,是否有预先填充Model :: find()或创建我自己的DocumentSet以便我可以使用数据?通常,我只是将其转换为数组并将其存储在缓存中。但是,我需要访问我编写的一些Model方法(例如:Customer :: fullName())
更新 :我发现了一些 ok 但不是很好的工作。我将Model :: find()结果保存为缓存$result->to('array')
中的数组。然后,在检索时,我遍历$ results并为每个$ result填充一个带Model::create($result, array("exists" => true)
的新数组;
答案 0 :(得分:4)
DocumentSet
返回的Model::find
包含一个Mongo数据库游标。在迭代项之前,它不会加载数据库中的所有数据。在迭代每个项目时,会创建一个Document
并将其缓存在DocumentSet对象的内存中。内置的php函数iterator_to_array()
可用于将DocumentSet转换为可以缓存的文档数组。
正如您在更新中提到的那样,您还可以使用->to('array')
准备缓存,然后使用Model::create()
进行备份。使用该方法的一个警告:当您使用->to('array')
时,它还将MongoId和MongoDate对象分别转换为字符串和整数。如果您为模型定义了$_schema
并设置了'id'
和'date'
类型,那么它们将被转换回{{1}返回的文档中的原始MongoId和MongoDate对象}}。如果您没有所有字段的架构,则可能会出现问题。我有recent pull request试图使Model::create()
能够在不转换本地mongo对象的情况下执行{(1}}(还修复了在子文档数组内部时总是被渲染的mongo对象的问题)。
FWIW,我实际上更喜欢只保存缓存中的数据,因为它比序列化整个php对象的空间更小,并且避免了在从缓存中提取项目时未定义的类或其他未初始化的项目的潜在问题。
我没有尝试过这个......但是我认为你可以制作一个缓存策略类来为你透明地处理这个问题。另一个非常谨慎的例子,使Lithium成为一个非常灵活和强大的框架。 http://li3.me/docs/lithium/storage/cache/strategy