我是MongoDB和C ++的新手。 我的问题:我想从我的数据库集合中更新JSON-Document:
{
"_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);
操作元素的一种方法是使用update-function:
collection.update_one(document{} << "docID" << docID
<< "docVersion" << docVersion
<< finalize,
document{} << "$set" << open_document <<
"userID" << "oscar@nds-local" << close_document << finalize);
但我不想操纵用户ID! 我想通过键&#34;部件&#34;来访问数组。 (取决于&#34; partID = u2v [...] 0KG7R&#34;)。 之后,我想更新/替换此数组的子元素partVersion,partKey和docPosition。 (1)我该怎么做?
此外,我想访问子阵列&#34;用户&#34;并添加键,删除键和操纵一个特殊用户的数组。 (2)我怎么能意识到这一点?
如果有人可以为我的问题(1)举个例子,那就太好了。我希望(1)的这个答案能给我一个如何处理问题(2)......
的线索答案 0 :(得分:0)
不需要从数据库中检索文档,您可以一口气更新文档。
您还需要使用dot notation:partID
在查询中添加parts.partID
字段,以在数组中找到一个匹配的对象。
要更新您请求的字段(1)并在users
中添加新键(2),您需要使用positional $ operator,因为它将允许访问查询匹配的元素。< / p>
它看起来像这样:
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。
以下代码段:
partKey
,partVersion
和
docPosition
字段,并在users
字段中为
partID:"AZ3[...]1Odeku"
部分 请注意,我已经从文档数据中将省略号…
替换为三个点...
,因为这导致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" : {
}
}
]
}