gpt4 book ai didi

c++ - MongoDB C++ 更新数组中的元素

转载 作者:太空宇宙 更新时间:2023-11-04 12:49:32 24 4
gpt4 key购买 nike

我对 MongoDB 和 C++ 还很陌生。我的问题:我想从我的数据库集合中更新一个 JSON 文档:

{
"_id" : ObjectId("5ac4beacc0e2a512e6377d43"),
"docID" : "SL/UO4ZJgdUxcRLKxXDWMg==",
"docVersion" : "DA3EF8047AD0F[…]77C6F9286488CEE6a",
"userID" : "bob@nds-local",
"parts" : [
{
"partID" : "u2v[…]0KG7R",
"partVersion" : "",
"partKey" : "",
"docPosition" : 0,
"counter" : 0,
"users" : {
"everyone" : [ 1, 0, 0, 0, 0, 0, 0, 0, 0 ]
}
},
{
"partID" : "AZ3[…]1Odeku",
"partVersion" : "",
"partKey" : "",
"docPosition" : 0,
"counter" : 0,
"users" : {
}
}
]
}

首先我想从我的数据库中获取这个文档。因此我正在使用这个小代码:

bsoncxx::stdx::optional<bsoncxx::document::value> resultDocument =
collection.find_one(document{} << "docID" << docID << finalize);

操作元素的一种方法是使用更新函数:

collection.update_one(document{} << "docID" << docID
<< "docVersion" << docVersion
<< finalize,
document{} << "$set" << open_document <<
"userID" << "oscar@nds-local" << close_document << finalize);

但我不想操纵用户 ID!我想使用键“parts”访问数组(取决于“partID=u2v[…]0KG7R”)。之后,我想更新/替换此数组的子元素 partVersion、partKey 和 docPosition。(1) 我该怎么做?

此外,我想访问子数组“用户”并添加键、删除键和操作一个特殊用户的数组。(2) 我怎么会意识到这一点?

如果有人能为我的问题 (1) 提供示例,那就太好了。我希望 (1) 的这个答案能给我一个如何处理问题 (2) 的线索......

最佳答案

不需要从数据库中检索文档,您可以一次性更新文档。

您还需要使用 dot notation 在查询中添加 partID 字段: parts.partID 查找数组中匹配的那个。

要更新您请求的字段 (1) 并在 users 中添加新键 (2) 您需要使用 positional $ operator因为它将允许访问与查询匹配的元素。

看起来像这样:

db["docs"].update_one(
make_document(
kvp("docID", docID),
kvp("parts.partID", partID)
),
make_document(
kvp("$set", make_document(
kvp("parts.$.partKey", newPartKey),
kvp("parts.$.partVersion", newPartVersion),
kvp("parts.$.docPosition", newDocPosition),
kvp("parts.$.users." + newUser, make_array(1,2,3,4,5))
)
)
)
);

kvp("parts.$.users."+ newUser, make_array(1,2,3,4,5)) 将在 users 中创建一个键具有 newUser 变量的值,它将包含数组 [1,2,3,4,5]

可以使用 $unset 运算符以类似的方式删除用户 (2):

db["docs"].update_one(
make_document(
kvp("docID", docID),
kvp("parts.partID", partID)
),
make_document(
kvp("$unset", make_document(kvp("parts.$.users." + userToDelete, "")))
)
);

如何操作一个特定用户 (2) 的数组将取决于您计划更新它的内容/方式,但为此您可以使用 array update operators .


以下代码片段:

  1. 首先,它更新 partKeypartVersiondocPosition 字段并在 users 字段中为partID:"AZ3[...]1Odeku" 部分
  2. 其次,删除之前添加的用户

请注意,我已经从您的文档数据中用三个点 ... 替换了省略号 ...,因为它导致 mongocxx 驱动程序永远不会即使在查询中也使用省略号也能找到任何匹配项(它在 mongo shell 中工作正常)

#include <iostream>

#include <bsoncxx/json.hpp>

#include <mongocxx/client.hpp>
#include <mongocxx/instance.hpp>
#include <mongocxx/uri.hpp>

using bsoncxx::builder::basic::kvp;
using bsoncxx::builder::basic::make_array;
using bsoncxx::builder::basic::make_document;

void updatePartAndAddNewUser(const mongocxx::client& client,
const std::string& docID,
const std::string& partID,
const std::string& newPartKey,
const std::string& newPartVersion,
int newDocPosition,
const std::string& newUser)
{
mongocxx::database db = client["stack"];

db["docs"].update_one(
make_document(
kvp("docID", docID),
kvp("parts.partID", partID)
),
make_document(
kvp("$set", make_document(
kvp("parts.$.partKey", newPartKey),
kvp("parts.$.partVersion", newPartVersion),
kvp("parts.$.docPosition", newDocPosition),
kvp("parts.$.users." + newUser, make_array(1,2,3,4,5))
)
)
)
);
}

void removeUserFromPart(const mongocxx::client& client,
const std::string& docID,
const std::string& partID,
const std::string& userToDelete)
{
mongocxx::database db = client["stack"];

db["docs"].update_one(
make_document(
kvp("docID", docID),
kvp("parts.partID", partID)
),
make_document(
kvp("$unset", make_document(kvp("parts.$.users." + userToDelete, "")))
)
);
}

int main(int, char**)
{
std::cout << "Start program" << std::endl;

mongocxx::instance instance{};
mongocxx::client client{ mongocxx::uri{} };

updatePartAndAddNewUser(client,
"SL/UO4ZJgdUxcRLKxXDWMg==",
"AZ3[...]1Odeku",
"newPartKey",
"newPartVersion1",
1,
"nobody");

std::cout << "Part has been modified, press any key to remove a user...";
std::cin.ignore();

removeUserFromPart(client,
"SL/UO4ZJgdUxcRLKxXDWMg==",
"AZ3[...]1Odeku",
"nobody");

std::cout << "End program" << std::endl;
}

在执行 updatePartAndAddNewUser(...) 后生成此文档:

{
"_id" : ObjectId("5ac4beacc0e2a512e6377d43"),
"docID" : "SL/UO4ZJgdUxcRLKxXDWMg==",
"docVersion" : "DA3EF8047AD0F[...]77C6F9286488CEE6a",
"userID" : "bob@nds-local",
"parts" : [
{
"partID" : "u2v[...]0KG7R",
"partVersion" : "",
"partKey" : "",
"docPosition" : 0,
"counter" : 0,
"users" : {
"everyone" : [1,0,0,0,0,0,0,0,0]
}
},
{
"partID" : "AZ3[...]1Odeku",
"partVersion" : "newPartVersion1",
"partKey" : "newPartKey",
"docPosition" : 1,
"counter" : 0,
"users" : {
"nobody" : [1,2,3,4,5]
}
}
]
}

在执行 removeUserFromPart(...) 之后,nobody 用户消失了:

{
"_id" : ObjectId("5ac4beacc0e2a512e6377d43"),
"docID" : "SL/UO4ZJgdUxcRLKxXDWMg==",
"docVersion" : "DA3EF8047AD0F[...]77C6F9286488CEE6a",
"userID" : "bob@nds-local",
"parts" : [
{
"partID" : "u2v[...]0KG7R",
"partVersion" : "",
"partKey" : "",
"docPosition" : 0,
"counter" : 0,
"users" : {
"everyone" : [1,0,0,0,0,0,0,0,0]
}
},
{
"partID" : "AZ3[...]1Odeku",
"partVersion" : "newPartVersion1",
"partKey" : "newPartKey",
"docPosition" : 1,
"counter" : 0,
"users" : {

}
}
]
}

关于c++ - MongoDB C++ 更新数组中的元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49707971/

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