I am kind of new into the AWS console and what not, I just wrote my own API (with the help of tutorials) and was wondering the following, can I update my product conditionally? My current param from the call looks like:
TableName: "product",
Key: {
product_id: event.pathParameters.id
},
UpdateExpression: "SET price_buyin = :price_buyin, price_sell = :price_sell, price_grit = :price_grit, note = :note, status_code = :status_code, producttype_id = :producttype_id, handled_by = :handled_by, handled_number = :handled_number, productsize_id = :productsize_id, processed_date = :processed_date",
ExpressionAttributeValues: {
":price_buyin": data.price_buyin ? data.price_buyin : 0,
":price_sell": data.price_sell ? data.price_sell : 0,
":price_grit": data.price_grit ? data.price_grit : 0,
":status_code": data.status_code ? data.status_code : 0,
":processed_date": data.processed_date ? data.processed_date : 0,
":producttype_id": data.producttype_id ? data.producttype_id : 0,
":handled_number": data.handled_number ? data.handled_number : 0,
":productsize_id": data.productsize_id ? data.productsize_id : 0,
":note": data.note ? data.note : "empty",
":handled_by": data.handled_by ? data.handled_by : "empty"
},
ReturnValues: "ALL_NEW"
I want to be able to update, lets say; price_buyin, but when I dont add the other values, they automatically become 0. Is there some way to say to only update price_buyin?
Thank you in advance!
Greetings,
Bram
I am pretty new to MongoDB and C++.
My problem: I want to update a JSON-Document from my database collection:
{
"_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" : {
}
}
]
}
First I want to get this document from my database. Therefore I am using this small code:
bsoncxx::stdx::optional<bsoncxx::document::value> resultDocument =
collection.find_one(document{} << "docID" << docID << finalize);
One way to manipulate an element is to use the update-function:
collection.update_one(document{} << "docID" << docID
<< "docVersion" << docVersion
<< finalize,
document{} << "$set" << open_document <<
"userID" << "oscar#nds-local" << close_document << finalize);
But I don't want to manipulate the userID!
I want to get access to the array with the key "parts" (depending on the "partID=u2v[…]0KG7R").
After that i want to update/replace the child-elements partVersion, partKey and docPosition of this array.
(1) How can I do that?
Furthermore I want to access the sub-array "users" and add keys, delete keys and manipulate the array of one special user.
(2) How could I realize this?
It would be great if someone can give me an example for my question (1). I hope that this answer of (1) will give me a clue of how to deal with question (2) ...
It is not required to retrieve the document from DB, you can update the document in one shot.
You need to add also the partID field in the query using the dot notation: parts.partID to find the one matching in the array.
To update the fields you requested (1) and to add a new key in users (2) you need to use the positional $ operator since it will allow accessing the element matched by the query.
It would look like this:
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))
)
)
)
);
The kvp("parts.$.users." + newUser, make_array(1,2,3,4,5)) will create a key inside users with the value of the newUser variable and it will contain the array [1,2,3,4,5]
Removing a user (2) can be done in a similar way using the $unset operator:
db["docs"].update_one(
make_document(
kvp("docID", docID),
kvp("parts.partID", partID)
),
make_document(
kvp("$unset", make_document(kvp("parts.$.users." + userToDelete, "")))
)
);
How to manipulate the array of one specific user (2) would depend on what/how exactly you plan to update it, but for that you can use the array update operators.
The following code snippet:
First, it updates the partKey, partVersion and
docPosition fields and adds a new user in the users field for the
partID:"AZ3[...]1Odeku" part
Second, it removes the previous added user
Please note that I've replaced the ellipsis … for three dots ... from your document data since it was causing that the mongocxx driver was never finding any match even if using also ellipsis in the query (it works fine in the 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;
}
Generates this document after executing 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]
}
}
]
}
and after executing removeUserFromPart(...) the nobody user is gone:
{
"_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" : {
}
}
]
}
Working native query
{
$match: {
$and : [
{userType:"200"},
{
$or: [
{login : /infosys/},
{email : /infosys/},
{firstName : /infosys/},
{lastName : /infosys/}
]
}
]
}
}
SpringData API which is not working as expected:
match(
Criteria.where("userType").is(userType).orOperator(
Criteria.where("login").regex(searchTxt).orOperator(
Criteria.where("email").regex(searchTxt).orOperator(
Criteria.where("firstName").regex(searchTxt).orOperator(Criteria.where("lastName").regex(searchTxt))
)
)
)
);
You are $or each criteria with the $or operator. orOperator takes a list of crtieria.
Below is the equivalent for your native query.
match
(
Criteria.where("userType").is(userType)
.orOperator(
Criteria.where("login").regex(searchTxt),
Criteria.where("email").regex(searchTxt),
Criteria.where("firstName").regex(searchTxt),
Criteria.where("lastName").regex(searchTxt)
)
)
I have 1.6 million documents in mongodb like this:
{
"_id" : ObjectId("57580c3f7e1a1469e772345b"),
"https://www.....com/vr/s1812227" : {
"suitability" : "children welcome",
"details" : {
"lookingCount" : 0,
"photoUrl" : "https://www.....com/vr/s1812227/....",
"partner" : null,
.........
}
.........
}
}
{
"_id" : ObjectId("57580c3f7e1a1469e772346d"),
"https://www.....com/vr/s1812358" : {
"suitability" : "children welcome",
"details" : {
"lookingCount" : 0,
"photoUrl" : "https://www.....com/vr/s1812358/....",
"partner" : null,
.........
}
.........
}
}
{
"_id" : ObjectId("57580c3f7e1a1469e772346d"),
"https://www.....com/vr/s1812358/unite/125" : {
"suitability" : "children welcome",
"details" : {
"lookingCount" : 0,
"photoUrl" : "https://www.....com/vr/s1812358/....",
"partner" : null,
.........
}
.........
}
}
I want like this:
{
"_id" : ObjectId("57580c3f7e1a1469e772345b"),
"products" : {
"suitability" : "children welcome",
"details" : {
"lookingCount" : 0,
"photoUrl" : "https://www.....com/vr/s1812227/....",
"partner" : null,
.........
}
.........
}
}
Edit content.... Thanks for your answer and interest in advance.
UPDATE
I'm trying this code but maximum 1200 documents insert to new collection. I have 1.5 million documents.
db.sourceColl.find().forEach(function(doc) {
for (var k in doc) {
if (k.match(/^https.*/) ) {
db.sourceColl.find({ "_id": doc._id });
db.getSiblingDB('targetdb')['targetColl'].insert({products: doc[k]});
}
}
});
After I'm try this and insert 20 documents to new collection. I'm so confused. how to rename and copy new collection all documents. UPDATE2: I use robomongo and I think there are limits in robomongo. This code works without problem in mongo shell. search, replace and copy new document.
var bulk = db.sourceColl.initializeOrderedBulkOp();
var counter = 0;
db.sourceColl.find().forEach(function(doc) {
for (var k in doc) {
if (k.match(/^https.*/) ) {
print(k)
bulk.find({ "_id": doc._id });
db.getSiblingDB('targetDB')['targetColl'].insert({products: doc[k]});
counter++;
}
}
if ( counter % 1000 == 0 ) {
bulk.execute();
bulk = db.sourceColl.initializeOrderedBulkOp();
}
});
if ( counter % 1000 != 0 )
bulk.execute();
I think there are limits in robomongo. This code works fine in mongo shell. search, replace and copy new collection.
var bulk = db.sourceColl.initializeOrderedBulkOp();
var counter = 0;
db.sourceColl.find().forEach(function(doc) {
for (var k in doc) {
if (k.match(/^https.*/) ) {
print(k)
bulk.find({ "_id": doc._id });
db.getSiblingDB('targetDB')['targetColl'].insert({products: doc[k]});
counter++;
}
}
if ( counter % 1000 == 0 ) {
bulk.execute();
bulk = db.sourceColl.initializeOrderedBulkOp();
}
});
if ( counter % 1000 != 0 )
bulk.execute();
I have modified this answer https://stackoverflow.com/a/25204168/6446251
I want to use regex in the aggregation's pipeline.
I originally did:
regex = '(foo|bar)'
regexDB = re.compile(regex, re.I|re.U )
db.col.find({
'events.display': True,
'$or' : [
{ 'events.description': regexDB } ,
{ 'events.title' : regexDB }
]
})
So I tried in the $match:
regex = '(foo|bar)'
regexDB = re.compile(regex, re.I|re.U )
db.col.aggregate([
{'$unwind': "$events"},
{'$match' :
{
'events.display' : True,
'$or' : [
{ '$events.description': regexDB } ,
{ '$events.title' : regexDB }
]
}
})
However it does not seem to work this way. The above code is based on this example. I also found an example here for mongo's shell.
How can I perform regex in pymongo's aggregation?