Mongocxx-更新文档中的数组



我在MongoDB中有一个文档,其结构如下:

{
"_id":"$oid":"621fbaeaeedd1c000e60fbd2"},
"username":"myuser",
"password":"mypassword",
"comments":["comment1", "comment2", "comment3"]
}

我有很多评论:

std::vector<std::string> mycomments; 
mycomments.push_back("comment2"); 
mycomments.push_back("comment4");

如果它还不存在,我想插入向量"的每个字符串;mycomments";进入阵列";评论";MongoDB文档中。我阅读了MongoDB文档,但我不明白如何使用函数"update_one";,在文档中,只有一个非常简单的案例。因此,我采用的解决方案如下:我获取注释的内容,并将其放入一个向量中,我将每个mycomments字符串推送到这个向量中(如果它还不存在(,然后我在MongoDB中删除该文档,并插入一个具有新值的新文档:

bsoncxx::stdx::optional<bsoncxx::document::value> res = collection.find_one(document{} << "username" << username << finalize);
if (res)
{
coll.delete_one(document{} << "username" << username << finalize);
document data_builder{};
data_builder << "username" << username << "password" << password;
auto array_builder = data_builder << "comments" << open_array;
for (std::string str : myNewVector)
{
array_builder << str;
}
array_builder << close_array;
bsoncxx::document::view_or_value doc = data_builder << finalize;
coll.insert_one(doc);
}

显然,这是一个非常愚蠢的解决方案,因为使用update_one函数就足够了,但从文档中我无法理解如何使用它(在这种复杂的情况下(。你能帮我吗?

如果你想保留订单,那么你必须获得文档,并且只推送其中尚未存在的注释。

然后,可以使用$push$each修饰符。以下是参考资料:https://docs.mongodb.com/manual/reference/operator/update/push/#append-数组的多个值

我运行了这个代码:

std::vector<std::string> mycomments;
mycomments.push_back("comment2");
mycomments.push_back("comment4");
auto eachDoc = document{};
auto arrayDoc = eachDoc << "$each" << open_array;
for (auto& comment : mycomments)
arrayDoc << comment;
arrayDoc << close_array;
auto findDoc = document{} << "username" << "myuser" << finalize;
auto update = document{} << "$push" << open_document << "comments" << eachDoc << close_document << finalize;
collection.update_one(findDoc.view(), update.view());

我获得了:["comment1", "comment2", "comment3", "comment2", "comment4"]

向数组中添加多个字符串而不重复的一种方法是使用$addToSet运算符和$each修饰符:

coll.update_one(
make_document( kvp("username", "myuser") ), // filter part
make_document(                              // update part
kvp("$addToSet",
make_document( kvp("comments",
make_document( kvp("$each",
make_array("comment2", "comment4")))))))
);

如果您想在不篡改现有字符串数组的情况下推送新元素,请尝试以下代码段:

bsoncxx::builder::basic::document update_builder;

/*Define the update to be performed on the document*/
bsoncxx::builder::basic::array new_array;
new_array.append("T1");
new_array.append("T2");
new_array.append("T3");
update_builder.append(kvp("$set", make_document(kvp("field_name", new_array))));

auto updating = update_builder.extract();

/*Update the document*/
auto result = m_dbCollection.update_one(filter.view(), updating.view());

为了清除字段中的现有元素并用新的字符串数组更新它,您可以尝试以下

/*Clear the existing data in the field*/
bsoncxx::builder::basic::document update_builder;
update_builder.append(kvp("$set",make_document(kvp("field_name", bsoncxx::types::b_array{}))));
auto update = update_builder.extract();

/*Define the update to be performed on the document*/
bsoncxx::builder::basic::array new_array;
new_array.append("T1");
new_array.append("T2");
new_array.append("T3");
update_builder.append(kvp("$set", make_document(kvp("field_name", new_array))));

auto updating = update_builder.extract();

/*Update the document*/
auto result = m_dbCollection.update_one(filter.view(), updating.view());

最新更新