在PHP中缓存MongoDB对象

6

我一直在尝试写出"好的代码",并使用依赖注入将数据库对象通过构造函数传递给我的类。

构造函数通常采用以下形式:

public function __construct(MongoDB $db) {
    $this->collection = $db->collectionName;
}

我注意到每次创建对象时都会创建一个MongoCollection实例。(即访问$db->collectionName 属性两次会返回两个不同的对象,而不是同一个对象)
我一直在使用ActiveRecord风格的基类,以便对象能够自我CRUD。
现在当我使用某种getAllRecords()函数,并且返回100多个这些对象时,就会创建100多个MongoCollection对象。(快速查看驱动程序源代码似乎表明对象在PHP中不止有新的表示,也会创建新的对象)
通过封装MongoMongoDB类并实现缓存来解决了这个问题。
class MyMongo extends Mongo
{
    private $objectCache = array();

    public function __get($name) {
        return array_key_exists($name, $this->objectCache)
            ? $this->objectCache[$name]
            : $this->objectCache[$name] = new MyMongoDB($this, $name);
    }
}

class MyMongoDB extends MongoDB
{
    private $objectCache = array();

    public function __get($name) {
        return array_key_exists($name, $this->objectCache)
            ? $this->objectCache[$name]
            : $this->objectCache[$name] = new MongoCollection($this, $name);
    }
}

我的问题如下:
  • MongoDB的这种行为是有意为之吗?它每次都返回一个新对象,这是个bug/feature还是PHP驱动程序或Mongo本身的问题(是否需要两个相同集合的对象)?
  • 如果缓存已创建并重用MongoDBMongoCollection对象,我会给自己造成问题吗?
  • 其他人通常如何处理MongoDB?我应该完全使用不同的方法吗?(例如:数据映射器)
谢谢,
Leigh.
2个回答

2

这是有意为之的,因为集合除了名称之外还与其它属性相关(目前是w和wtimeout,未来会计划更多)。如果你只关心名称,那么缓存它们就可以了。


谢谢@kristina,我认为我需要对w或wtimeout进行的任何更改都将在所有集合中相同,因此似乎只关心集合的名称。我可以问一下您通常如何管理数据对象吗?您使用ActiveRecord、DataMapper、其他什么东西,还是只是看起来最适合的? - Leigh
我写了这个驱动程序,所以我的知识大多是理论性的 :) 有更多实践经验的用户可能更有资格回答你问题的第三部分。 - kris
我知道你写了这个驱动程序,这就是为什么我一直纠缠你的原因;) - 但感谢你抽出时间来,我知道PHP聊天室里有些人在使用Mongo,我会去麻烦他们。 - Leigh

1

我一直将MongoCollection传递给我的对象,而不是MongoDb。我的理由是在对象中选择集合会产生隐藏的依赖关系(可能过度设计),然后在我的单元测试中,我可以模拟MongoCollection对象。


我的构造函数实际上包含了 parent::__construct($db->collection)我的想法 是一个对象知道自己的集合是什么是可以接受的,而且我不想在对象外部跟踪数百个集合。 - Leigh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接