Because of a weird bug in my code, I have a collection with field names which are stricly numbers (ex: 34344,54675,34356).
Now I try to move these fields values to another fields (ex: name,email,etc) but when I run the update command:
db.collection.find({"id_field" : 1996}).forEach(function (elem) {db.collection.update({_id: elem._id},{$set: {name: elem.36536}});});
All I get is an error:
SyntaxError: Unexpected number
How should I handle it? I already tried with elem[36536] instead elem.36536 but without success.
if I got your problem right, this code might help you:
db.collection.find({"id_field" : 1996}).forEach(function (elem)
{
var value = elem['36536'];
db.collection.update({_id: elem._id},{$set: {name: value}});
});
If your document is like this
{
"_id" : 1,
"elem" : {
"123" : "barno",
"456" : "foo#gmail.com"
}
}
you can $rename the key document.
db.d.update({"_id" : 1},{$rename:{'elem.123':'elem.name','elem.456':'elem.email'}})
Result:
{
"_id" : 1,
"elem" : {
"name" : "barno",
"email" : "foo#gmail.com"
}
}
Related
I have MongoDB Collection where some documents have arrays of objects. One of the fields of this objects is timestamp.
The problem is that historically some of timestamp values are Strings (e.g. '2018-02-25T13:33:56.675000') or Date and some of them are Double (e.g. 1528108521726.26).
I have to convert all of them to Double.
I've built the query to get all the documents with the problematic type:
db.getCollection('Cases').find({sent_messages: {$elemMatch:{timestamp: {$type:[2, 9]}}}})
And I also know how to convert Date-string to double using JS:
new Date("2018-02-18T06:39:20.797Z").getTime()
> 1518935960797
But I can't build the proper query to perform the update.
Here is an example of such a document:
{
"_id" : ObjectId("6c88f656532aab00050dc023"),
"created_at" : ISODate("2018-05-18T03:43:18.986Z"),
"updated_at" : ISODate("2018-05-18T06:39:20.798Z"),
"sent_messages" : [
{
"timestamp" : ISODate("2018-02-18T06:39:20.797Z"),
"text" : "Hey",
"sender" : "me"
}
],
"status" : 1
}
After the update it should be:
{
"_id" : ObjectId("6c88f656532aab00050dc023"),
"created_at" : ISODate("2018-05-18T03:43:18.986Z"),
"updated_at" : ISODate("2018-05-18T06:39:20.798Z"),
"sent_messages" : [
{
"timestamp" : 1518935960797.00,
"text" : "Hey",
"sender" : "me"
}
],
"status" : 1
}
As per your question, you are trying to fetch the record first.
db.getCollection('Cases').find({sent_messages: {$elemMatch:{timestamp: {$type:[2, 9]}}}})
Then convert date in JS:
new Date("2018-02-18T06:39:20.797Z").getTime()
And then this is an update query:
db.getCollection('Cases').updateOne({_id:ObjectId("6c88f656532aab00050dc023")}, { $set: { "sent_messages.$.timestamp" : "218392712937.0" }})
And if you want to update all records then you should write some forEach mechanism. I think you have already this implemented.
Hope this may help you.
Finally I just do it with JS code that can be run in mongo console:
db.getCollection('Cases').find({sent_messages: {$elemMatch:{timestamp: {$type:[2, 9]}}}}).forEach(function(doc) {
print('=================');
print(JSON.stringify(doc));
doc.sent_messages.forEach(function(msg){
var dbl = new Date(msg.timestamp).getTime();
print(dbl);
msg.timestamp = dbl;
});
print(JSON.stringify(doc))
db.Cases.save(doc);
} )
Thanks all for your help!
Actually have 2 documents: Histories and Subsidiaries, but I forgot add to Histories the subsidiary name.
Histories Document:
{
"_id" : ObjectId("59480f91ba4d070b882ff924"),
"subsidiary" : ObjectId("5947fdf3ba4d070b882ff851"),
"campaignTitle" : "Prueba Autoredeeem",
"campaignId" : ObjectId("5948004fba4d070b882ff886"),
}
Subsidiary Document
{
"_id" : ObjectId("5947fdf3ba4d070b882ff851"),
"loginId" : 50174,
"name" : "Sucursal Alpha",
}
Now I need update History Document, add a "subsidiaryName" field with "Subsidiary.name" value from Subsidiary Document
This is my first aproach:
db.getCollection('couponredeemhistories')
.updateMany({}, {$set: {subsidiaryName:
db.getCollection('subsidiaries')
.findOne({"_id": ObjectId('5947fdf3ba4d070b882ff851')}, {_id: 0,name: 1})}})
But, the result gives me an Object inside subsidiaryName, instead flat text.
{
"_id" : ObjectId("59480f91ba4d070b882ff924"),
"subsidiary" : ObjectId("5947fdf3ba4d070b882ff851"),
"campaignDescription" : "",
"campaignTitle" : "Prueba Autoredeeem",
"campaignId" : ObjectId("5948004fba4d070b882ff886"),
"subsidiaryName" : {
"name" : "Sucursal Alpha"
}
}
Then, I have 2 problems:
How to set only flat text value to subsidiaryName field?
R: Add .name to project for get flat text
How to set .findOne() "id" param for current document instead ObjectId('HARD CODE')?
R: Iterate with forEach Cursor
IMPORTANT LIMITS: this is for MongoDB Shell (MongoDB 3.4)
Thank you, please support me for fix any language issues on this question.
Updated Answers thanks to #Astro:
db.getCollection('couponredeemhistories').find()
.forEach(function(doc){
if(doc.subsidiary !== undefined){
doc.subsidiaryName = db.getCollection('subsidiaries').findOne({'_id': doc.subsidiary}, {_id: 0, name: 1}).name;
db.getCollection('couponredeemhistories').save(doc);
}
})
Try this:
db.getCollection('couponredeemhistories')
.updateMany({}, {$set: {subsidiaryName:
db.getCollection('subsidiaries')
.findOne({"_id": ObjectId('5947fdf3ba4d070b882ff851')}, {_id: 0,name: 1}).name}})
In mongodb. I have the following document/json with these (4) fields.
"ready_state" : {
"user" : "abcd#abc.com",
"state" : "green",
"audit_date" : ISODate("2016-04-03T14:27:11.494Z"),
"profile" : "tst"
},
How do I empty out this hash? Output expected would be:
"ready_state" : {
},
Can someone provide example on how to do so using pull and set?
You simply replace the value of ready_state with the new value. Using $set you can do something like this:
db.collection.update(query, { $set: { ready_state: {} });
how can I return a specific value for a specific document in MongoDB? For example, I have a schema that looks like:
{
"_id" : "XfCZSje7GjynvMZu7",
"createdAt" : ISODate("2015-03-23T14:52:44.084Z"),
"services" : {
"password" : {
"bcrypt" : "$2a$10$tcb01VbDMVhH03mbRdKYL.79FPj/fFMP62BDpcvpoTfF3LPgjHJoq"
},
"resume" : {
"loginTokens" : [ ]
}
},
"emails" : {
"address" : "abc123#gmu.edu",
"verified" : true
},
"profile" : {
"companyName" : "comp1",
"flagged" : true,
"phoneNum" : "7778883333"
}}
I want to return and store the value for profile.flagged specifically for the document with _id : XfCZSje7GjynvMZu7. So far I have tried:
db.users.find({_id:'myfi3E4YTf9z6tdgS'},{admin:1})
and
db.users.find({_id: 'myfi3E4YTf9z6tdgS'}, {profile:admin});
I want the query to return true or false depending on the assigned value.
Can someone help? Thanks!
MongoDB queries always return document objects, not single values. So one way to do this is with shell code like:
var flagged =
db.users.findOne({_id: 'myfi3E4YTf9z6tdgS'}, {'profile.flagged': 1}).profile.flagged;
Note the use of findOne instead of find so that you're working with just a single doc instead of the cursor that you get with find.
The correct answer here is the method .distinct() (link here)
Use it like this:
db.users.find({_id:'myfi3E4YTf9z6tdgS'},{admin:1}).distinct('admin')
The result will be: 1 or 0
I have a document like this,
{
"S" : {
"500209" : {
"total_income" : 38982,
"interest_income" : 1714,
"reported_eps" : 158.76,
"year" : 201303
}
},
"_id" : "pl"
}
I am trying to update this document like this,
{
"S" : {
"500209" : {
"total_income" : 38982,
"interest_income" : 1714,
"reported_eps" : 158.76,
"year" : 201303,
"yield": 1001, <== inserted a new attribute
}
},
"_id" : "pl"
}
I have tried this,
db.my_collection.update({_id: 'pl'},{$set: {'S.500209.yield': 1}})
But I couldn't make it. And I searched in stack overflow and google but I couldn't find out.
I got so many answers but most of them keeping sub-docuemnts in array.
Pleas help me to solve my issue, and please tell me why most of them keeping subdocuments in array.
Number key might cause the problem. Update your field name.
db.my_collection.update({_id: 'pl'},{$set: {'S.a500209.yield': 1}})
EDIT
Upgrade mongo version. It works fine with 2.4.