2012-09-05 52 views
4

我想将Model :: find()返回的DocumentSet存储在memcached中。但是,当我从缓存中检索结果后尝试处理结果时,我得到下面的MongoException。具体地,使用的foreach时,该异常被\数据\源的63线呼叫时if ($this->_resource->hasNext())抛出\ mongo_db \ Result.php使用Memcached缓存Model :: find()的结果

MongoException

的MongoCursor对象还没有被正确初始化通过其构造函数

我可以理解为什么会出现这种情况。

我的问题是,是否有预先填充Model :: find()或创建我自己的DocumentSet,以便我可以使用数据?通常,我只是将其转换为数组并将其存储在缓存中。但是,我需要访问一些我写的模型方法(例如:客户::全名())

更新:我发现有点workound那就是OK但不是很好。我将Model :: find()结果保存为缓存$result->to('array')中的一个数组。然后,检索后,我循环遍历$结果,并为每个$ result填充一个新的数组,其中包含Model::create($result, array("exists" => true);

回答

4

A DocumentSetModel::find返回包含一个Mongo数据库游标。它不会加载数据库中的所有数据,直到迭代项目。随着每个项目的迭代,将创建一个Document并将其缓存到DocumentSet对象的内存中。内置的php函数iterator_to_array()可用于将DocumentSet转换为您可缓存的文档数组。

正如您在更新中提到的那样,您还可以使用->to('array')准备缓存,然后使用Model::create()将其备份。使用该方法的一个警告:当您使用->to('array')时,它也分别将MongoId和MongoDate对象转换为字符串和整数。如果您已为您的模型定义$_schema并设置了'id''date'类型,则它们将被转换回由Model::create()返回的文档中原始的MongoId和MongoDate对象。如果您没有适用于所有字段的模式,则可能会出现问题。我有一个recent pull request,它试图使->to('array')没有投射本地mongo对象(也解决了mongo对象在子文档数组内部时总是被投射的问题)的可能性。我实际上更喜欢将数据保存在缓存中,因为它的空间少于序列化整个php对象的空间,并避免了未定义类或其他项未从缓存中取出时未初始化的其他项。

我还没有尝试过这个......但是我认为你可以制定一个缓存策略类来为你透明地照顾它。另一个让Lithium成为一个非常灵活和强大的框架的非常谨慎的例子。 http://li3.me/docs/lithium/storage/cache/strategy

+0

我喜欢你的自定义策略想法。目前,我依靠$ _schema进行正确的类型转换。 –