使用mongo c ++驱动程序查询嵌套的BSON文档

时间:2019-11-25 20:27:30

标签: c++ json mongodb bson mongo-cxx-driver

我有一个items: [ { //New button calls the Add Record form to pass inputs to the store text: 'New', scope: this, handler: function(){ testForm.show(); } },{ text: 'Update', scope: this, handler: function(){ //WIP var selection = Ext.getCmp('testGrid').getView().getSelectionModel().getSelection()[0]; if (selection) { testForm.show(); testForm.loadRecord(selection); } } }//Delete button is irrelevant ] 和一个bsoncxx::document::view bsonObjView,它们代表我们要在BSON文档中搜索的值的键(第一个键是顶层,第二个键是深度1,第三个键深度是2,等)。

我正在尝试编写一个给定路径的函数来搜索bson文档:

std::vector<std::string> path

如何使该功能起作用? bsoncxx::document::element deepFieldAccess(bsoncxx::document::view bsonObj, const std::vector<std::string>& path) { assert (!path.empty()); // for each key, find the corresponding value at the current depth, next keys will search the value (document) we found at the current depth for (auto const& currKey: path) { // get value for currKey bsonObj = bsonObj.find(currKey); } // for every key in the path we found a value at the appropriate level, we return the final value we found with the final key return bsonObj; } 应该采用哪种类型才能在循环中进行此类搜索?另外,如何检查是否找到bsonObj的值?

还可以通过某种方式构建bsoncxx吗?

这是一个示例json文档,后跟一些指向其中的值的路径。给定路径后,最终解决方案应返回相应的值:

currKey

示例路径:

路径{ "shopper": { "Id": "4973860941232342", "Context": { "CollapseOrderItems": false, "IsTest": false } }, "SelfIdentifiersData": { "SelfIdentifierData": [ { "SelfIdentifierType": { "SelfIdentifierType": "111" } }, { "SelfIdentifierType": { "SelfIdentifierType": "2222" } } ] } } 指向字符串[ shopper -> Id -> targetValue ]

路径"4973860941232342"指向对象[ SelfIdentifiersData -> SelfIdentifierData -> array_idx: 0 -> targetValue ]

路径{ "SelfIdentifierType": { "SelfIdentifierType": "111" } }指向对象[ SelfIdentifiersData -> SelfIdentifierData -> array_idx: 0 -> SelfIdentifierType -> targetValue ]

路径{ "SelfIdentifierType": "111" }指向字符串[ SelfIdentifiersData -> SelfIdentifierData -> array_idx: 0 -> SelfIdentifierType -> SelfIdentifierType -> targetValue ]

请注意,路径的类型为"111"。因此,最终解决方案应返回路径指向的值。它应该适用于任意深度,也适用于指向TO数组元素的路径(第二个示例路径)和THROUGH数组元素的路径(最后两个示例路径)。我们假定索引为std::vector<std::string> path的数组元素的键为i

更新:当前,@ acm建议的方法无法用于具有数组索引的路径(没有数组索引的路径可以正常工作)。这是重现此问题的所有代码:

"i"

1 个答案:

答案 0 :(得分:1)

没有内置的方法可以执行此操作,因此您将需要编写一个辅助函数,就像上面概述的那样。

我相信您遇到的问题是该函数的参数为​​bsoncxx::document::view,但是view::find的返回值为bsoncxx::document::element。因此,您需要考虑循环中某处类型的变化。

我想我会这样写函数:

bsoncxx::document::element deepFieldAccess(bsoncxx::document::view bsonObj, const std::vector<std::string>& path) {

    if (path.empty())
       return {};

    auto keysIter = path.begin();
    const auto keysEnd = path.end();

    auto currElement = bsonObj[*(keysIter++)];
    while (currElement && (keysIter != keysEnd))
        currElement = currElement[*(keysIter++)];

    return currElement;
}

请注意,如果找不到路径的任何部分,或者如果路径尝试遍历到实际上不是BSON文档或BSON数组的对象,则这将返回无效的bsoncxx::document::element