移动副本和/或分配mongodb cxx游标

时间:2017-10-05 13:27:10

标签: c++ mongodb qt mongo-cxx-driver

我正在编写一系列围绕mongodb-cxx类的类,以使它们符合我的应用程序的其余部分的存储API,这是用Qt编写的。

我不需要Mongo的完整功能集,基本上只需要CRUD:创建,读取,更新,删除和查找,或者传入一些更高级的参数(读/写问题等)。

我曾想在mongocxx :: cursor周围创建一个包装类,以便find()的结果可以“以后”以存储API使用的数据格式进行迭代。 “稍后”我的意思是(包装的)游标返回到一个抽象类,它可以迭代结果并根据模式验证数据,或者可以跳过条目,或者可以将组(异步)结果发送到结尾客户等

例如,如果我有:(这个例子略有缩写)

using namespace mongocxx;

class QMongoClient
{
    static instance _instance;

    QMongoClient(QString url) : _client( uri( qPrintable(url) ) );  
    client _client;
    QMongoDatabase operator[](QString d);
};

class QMongoDatabase
{
    QMongoDatabase(database db) : _database(db);
    database _database;
    QMongoCollection operator [](QString c);
};

class QMongoCollection
{
    QMongoCollection(collection c) : _collection(c);
    collection _collection;
    //create... same as insert()
    //read... same as find_one()
    //update... same as upsert() or update()
    //delete...
    //find... a query will be provided
    QMongoCursor findAll() { cursor c = _collection.find({}); return QMongoCursor(c); };
};

class QMongoCursor
{
    QMongoCursor(cursor c) : _cursor(c);
    //copy/move/assign constructors needed, probably

    cursor _cursor;

    QString data(); //return document contents as JSON string, for instance

    //begin() <-- iterator
    //end() <-- iterator
};

我原本希望这个方法能够正常工作,直到游标抛出编译器错误为止:

error: call to implicitly-deleted copy constructor of 'mongocxx::v_noabi::cursor'

这个想法是做类似的事情:

QMongoClient client("mongodb://url...");
QMongoDatabase db = client["somedbname"];
QMongoCollection coll = db["somecollection"];
QMongoCursor c = coll.findAll();

//or more abbreviated:
QMongoCursor c = client["somedbname"]["somecollection"].findAll();

//iterate over c here as needed, or send it to another abstraction layer...

我认为这种情况正在发生,因为mongocxx :: cursor对象并不打算传递,当它们超出范围时它们就会被销毁。

例如,当QMongoCursor :: findAll()完成时,返回的游标将被销毁,并且无法在QMongoCursor构造函数中复制。

findAll()函数在那一刻检索所有文档并返回它们(可能是未知的结果集大小)似乎效率很低。例如,我希望能够一次检索10个结果,然后通过网络将它们异步发送到终端客户端。

所以问题是:是:

  • 如果光标超出范围并且没有复制/移动构造函数,如何将光标保持活动状态
  • 或如何创建指向游标的指针并知道它的生命周期以及何时删除它
  • 还有另一种方法可以解决这个问题吗?我一直在查看文档但没找到它。

我认为我缺少一些c ++语法或机制,比如移动分配或类似的东西。

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

好吧,mongocxx::cursor个对象可移动的,但你没有要求它被移动,你要求复制。尝试:

QMongoCursor(cursor c) : _cursor(std::move(c));

您可能也希望为QDatabase和QCollection构造函数执行此操作。

您应该考虑的一件事是,如果您要构建更高级别的工具包,则需要密切关注与clientdatabasecollection相关的生命周期规则,和cursor个对象。您可能会发现构建shared_ptr类似的抽象以确保类型系统强制执行适当的生命周期对您的用例有利。

我们没有让司机以这种方式工作,因为我们不想强迫人们做出决定。相反,我们觉得它可以而且应该被委托给更高层次的抽象,可能就像你正在构建的那样。