gpt4 book ai didi

c++ - 您可以更改 bsoncxx 对象(文档/值/元素)吗?

转载 作者:太空狗 更新时间:2023-10-29 23:13:38 25 4
gpt4 key购买 nike

我正在使用 mongocxx 驱动程序,我正在考虑将 BSON 中给出的查询结果作为数据持有者保存在几个对象中,而不是解析 BSON 以检索值然后丢弃它.

如果”我可以即时编辑 BSON,这会有些意义。除了构建器之外,我在 bsoncxx 驱动程序文档中找不到任何允许我在构建后操作 bsoncxx 文档/值/ View /元素的内容。

举个例子,假设我有这样的东西

fruit["orange"];

其中 fruit 是一个 bsoncxx::document::element

我可以使用 .get_xxx 运算符之一获取值

我找不到的是类似的东西

fruit["orange"] = "ripe";

有没有办法做到这一点,或者构建器背后的想法“只是”创建一个查询以提供给数据库?

最佳答案

有一个相同主题的问题,参见here

所以,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();
}

用法:

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;

结果:

{
“foo0”:“bar0”,
“foo1”:1,
“foo2”:314
}
{
“foo0”:“bar0”,
“foo1”:“编辑”,
“foo2”:314,
“baz_append”:123
}

所以,在你的情况下你可以使用

fruit = editBsoncxx<std::string>(fruit.view(), "orange", "ripe");

但是,再一次,see already-mentioned related question你说的对

the idea behind the builder is "just" to create a query to give to the database?

我认为,解决方案是“不要编辑文档”。

你也可以写一些类似类型转换器的东西,从 bsoncxx 到其他 json 存储格式(例如,rapidjson)
当心 {value:"valid_json"}:bsoncxx::to_json 不会在值中的引号中添加反斜杠 => 可以进行注入(inject)。

关于c++ - 您可以更改 bsoncxx 对象(文档/值/元素)吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37940723/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com