【问题标题】:Using Memcached to cache results from Model::find()使用 Memcached 缓存 Model::find() 的结果
【发布时间】:2014-02-28 09:34:51
【问题描述】:

我想将从 Model::find() 返回的 DocumentSet 存储在 memcached 中。但是,当我从缓存中检索结果后尝试处理结果时,我得到了下面的 MongoException。具体来说,使用foreach时,在\data\source\mongo_db\Result.php的第63行调用if ($this->_resource->hasNext())时抛出异常

MongoException

MongoCursor 对象没有被它的构造函数正确初始化

我能理解为什么会这样。

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

更新:我发现了一个ok但不是很好的解决方法。我将 Model::find() 结果保存为缓存$result->to('array') 中的数组。然后,在检索时,我遍历 $results 并为每个 $result 填充一个带有 Model::create($result, array("exists" => true) 的新数组;

【问题讨论】:

    标签: memcached lithium


    【解决方案1】:

    Model::find 返回的 DocumentSet 包含一个 Mongo db 游标。在迭代项目之前,它不会从数据库中加载所有数据。在迭代每个项目时,会创建一个 Document 并将其缓存在内存中的 DocumentSet 对象中。内置的 php 函数 iterator_to_array() 可用于将 DocumentSet 转换为可以缓存的文档数组。

    正如您在更新中提到的,您还可以使用->to('array') 准备缓存,然后使用Model::create() 进行备份。该方法的一个警告:当您使用 ->to('array') 时,它还会将 MongoId 和 MongoDate 对象分别转换为字符串和整数。如果您为模型定义了$_schema 并设置了'id''date' 类型,它们将被转换回Model::create() 返回的Document 中的原始MongoId 和MongoDate 对象。如果您没有所有字段的架构,则可能会出现问题。我有一个recent pull request,它试图让->to('array') 在不强制转换原生 mongo 对象的情况下成为可能(还解决了在子文档数组中总是强制转换 mongo 对象的问题)。

    FWIW,我实际上更喜欢只将数据保存在缓存中,因为它比序列化整个 php 对象的空间更小,并且避免了从缓存中提取项目时未定义类或未初始化其他项目的潜在问题。

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

    【讨论】:

    • 我喜欢你的自定义策略想法。目前,我依靠 $_schema 进行正确的类型转换。
    猜你喜欢
    • 1970-01-01
    • 2017-01-04
    • 2018-06-13
    • 1970-01-01
    • 1970-01-01
    • 2012-06-07
    • 1970-01-01
    • 2010-11-22
    • 1970-01-01
    相关资源
    最近更新 更多