mongodb Mongocxx -更新文档中的数组?

js4nwp54  于 2023-02-07  发布在  Go
关注(0)|答案(3)|浏览(171)

我在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");

我想把向量“mycoments”的每个字符串插入MongoDB文档中的数组“comments”中,如果还没有的话。我看过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函数就足够了,但是从文档中我不明白如何使用它(在这个复杂的情况下)。

hivapdat

hivapdat1#

如果您想保持顺序,那么您必须获取文档,并且只推送文档中不存在的注解。
然后,您可以使用$push$each修饰符。https://docs.mongodb.com/manual/reference/operator/update/push/#append-multiple-values-to-an-array
我运行了这个代码:

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"]

ggazkfy8

ggazkfy82#

将多个字符串添加到数组中而不重复的一种方法是使用$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")))))))
);
qpgpyjmq

qpgpyjmq3#

如果要推送新元素而不篡改现有字符串数组,请尝试以下代码段:

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());

相关问题