我正在使用mongocxx驱动程序,并且正在考虑将 BSON 中给出的查询结果保留为几个对象中的数据持有者,而不是解析 BSON 以检索值然后丢弃它。
“如果”我可以即时编辑 BSON,这将有意义。除了构建器之外,我在bsoncxx驱动程序文档中找不到任何可以让我在构建后操作bsoncxx文档/值/视图/元素的内容。
举个例子,想象我有这样的东西
fruit["orange"];
Run Code Online (Sandbox Code Playgroud)
哪里fruit是一个bsoncxx::document::element
我可以通过使用其中之一来获取该值.get_xxx operators。
我找不到的是类似的东西
fruit["orange"] = "ripe";
Run Code Online (Sandbox Code Playgroud)
有没有办法做到这一点,或者构建器背后的想法“只是”创建一个查询以提供给数据库?
小智 0
有一个相同主题的问题,请参阅此处
因此,bsoncxx 对象似乎是不可变的,如果我们需要编辑它们,我们必须重新创建它们..:(
我写了一个非常糟糕的解决方案,它从头开始重新创建文档
但我想这是一个解决方案。
std::string bsoncxx_string_viewToString(core::v1::string_view gotStringView) {
std::stringstream convertingStream;
convertingStream << gotStringView;
return std::move(convertingStream.str());
}
std::string b_utf8ToString(bsoncxx::types::b_utf8 gotB_utf8) {
return std::move(bsoncxx_string_viewToString(core::v1::string_view(gotB_utf8)));
}
template <typename T>
bsoncxx::document::value editBsoncxx(bsoncxx::document::view documentToEdit, std::string keyToEdit, T newValue, bool appendValueIfKeyNotExist = true) {
auto doc = bsoncxx::builder::stream::document{};
std::string currentKey;
for (auto i : documentToEdit) {
currentKey = bsoncxx_string_viewToString(i.key());
if (currentKey == keyToEdit) {
doc << keyToEdit << newValue;
appendValueIfKeyNotExist = false;
} else {
doc << currentKey << i.get_value();
}
}
if (appendValueIfKeyNotExist) // Maybe this would be better with documentToEdit.find(key), but I don't know how to check if iterator is past-the-end
//If there is a way to check if bsoncxx contains key, we can achieve ~o(log(n)) [depending on 'find key' implementation] which is better than o(n)
doc << keyToEdit << newValue;
return doc.extract();
}
Run Code Online (Sandbox Code Playgroud)
用法:
auto doc = document{} << "foo0" << "bar0" << "foo1" << 1 << "foo2" << 314 << finalize;
std::cout << bsoncxx::to_json(doc) << std::endl << std::endl;
doc = editBsoncxx<std::string> (doc.view(), "foo1", "edited"); //replace "foo1" with string "edited"
doc = editBsoncxx<int>(doc.view(), "baz_noappend", 123, false); //do nothing if key "baz_noappend" is not found. <- if key-existance algorythm will be applied, we'd spend about o(lob(n)) here, not o(n)
doc = editBsoncxx<int>(doc.view(), "baz_append", 123, true); //key will not be found => it'll be appended which is default behaviour
std::cout << bsoncxx::to_json(doc) << std::endl;
Run Code Online (Sandbox Code Playgroud)
结果:
{
"foo0" : "bar0",
"foo1" : 1,
"foo2" : 314
}
{
"foo0" : "bar0",
"foo1" : "edited",
"foo2" : 314,
"baz_append" : 123
}
所以,在你的情况下你可以使用
fruit = editBsoncxx<std::string>(fruit.view(), "orange", "ripe");
Run Code Online (Sandbox Code Playgroud)
但是,再次,请参阅已经提到的相关问题,你说得对
构建器背后的想法是“只是”创建一个查询以提供给数据库?
我认为,解决方案是“不要编辑文档”。
您也可以编写类似类型转换器的内容,从 bsoncxx 到其他 json 存储格式(例如,rapidjson)。
注意 {value:"valid_json"}:bsoncxx::to_json 不会在值中添加反斜杠来引号 => 注入可以制成。
| 归档时间: |
|
| 查看次数: |
2105 次 |
| 最近记录: |