I have to interchange the values of a document.
var query = {"_id" : ObjectId("53e1c254382f891cc600076d")};
db.properties.find(query).forEach(function(prop){
printjson({"_id":prop._id, "val":prop.val, "ua":prop.ua});
db.properties.update(query, {$set:{ua: prop.val}},{$unset:{val:""}});
});
Before update operation, document looks like this:
{
"_id" : ObjectId("53e1c254382f891cc600076d"),
"val" : 9876541,
"ua" : null
}
And after the update it turns to:
{
"_id" : ObjectId("53e1c254382f891cc600076d"),
"val" : 9876541,
"ua" : 9876541
}
But I expect it as:
{
"_id" : ObjectId("53e1c254382f891cc600076d"),
"val" : null,
"ua" : 9876541
}
But its not working. also setting "val" null ({$set:{val:null}}) directly it deleted my entire document.
Setting undefined, It worked like a charm!!
db.properties.find(query).forEach(function(prop){
db.properties.update(query, {$set:{ua: prop.val, val:undefined}});
});
I know this is old, but your syntax for the update function is wrong. The update object should be one single object: db.properties.update(query, {{$set:{ua: prop.val}},{$unset:{val:""}}});
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!
I'm using pymongo's map_reduce framework for extracting some data out from mongodb. This is how my data look like:
{
"_id" : ObjectId("566f570e3816dc2fe631db4f"),
"property_id" : 5594.0000000000000000,
"reservation_id" : "2544430.1",
"updated" : ISODate("2015-12-15T02:04:33.000Z"),
"offer_list" : {
"68799" : {
"pitched" : "no",
"accepted" : "no"
},
"68801" : {
"pitched" : "no",
"accepted" : "no"
}
},
"status" : "awarded",
"comments" : "",
"agent_id" : 1.0000000000000000,
"created" : ISODate("2015-12-14T23:55:52.000Z")
}
I will need to get all record counts for each agent after some date using pymongo.
The mapper function would look like:
mapper = Code("""function(){
if(this.created>start_date){
emit(this.agent_id, 1);
})
in which start_date would be a variable passed in from python code.
By reading the document I think the scope should be set but I could not find any documentation on how to do that. I knew nothing about javascript. Can anyone help?
Thanks in advance!
The problem was fixed using the query keyword.
collection.map_reduce(mapper, reducer, "myresults", query={"created":{"$gte":start_date, "$lt":end_date}})
I try to update a field in a collection that contains an array with $push. Instead of adding the value, the document gets replaced by a document containing only _id. If I do the update in the mongo-console it works.
Here's the code: (Serverside)
Meteor.methods({
dismiss: function (jobId,userId) {
Jobs.update(jobId, {$push : {dismissed: userId}},{validate: false},function(){});
},
});
The document in mongodb before looks like this:
{ "_id" : "MBfQ39BsKwqspLLEL", "title" : "Derniset edolar ingreadcomi permaap manthe soi ti.", "description" : "Siter tersion ingtery enlaringvi disicgen yma.", "wage" : 10, "wagePeriod" : "hour", "currency" : "Euro", "image" : "xGDcPNXjn7kpa2mv2", "createdAt" : ISODate("2015-06-18T06:40:47.575Z") }
And after the operation it looks like this:
{ "_id" : "MBfQ39BsKwqspLLEL" }
Any help appreciated.
Thanks.
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
When I issue the following query:
db.users.find({"pic.status" : {$ne : null} }, {"pic" : 1}).toArray()
I expect to receive all users whose pic.status is NOT null. However, the actual result looks something like this:
{
"_id" : ObjectId("4f1e1ab9cdf9dbaa160000bf"),
"pic" : {
"id" : "4f1e1ab9cdf9dbaa160000be",
"status" : null
}
},
{
"_id" : ObjectId("4f1e28480eaf38193d00006f"),
"pic" : {
"id" : "4f1e28480eaf38193d00006e",
"status" : null
}
}
That is, I receive users whose pic.status IS null. How can I fix this?
I know it's an old question, and might not be relevant anymore, but as there was no accepted answer, I thought I'll comment for anyone looking for answer.
I was able to reproduce the problem on MongoDB version 2.4.9.
> db.sourceListings.findOne({displayed:{$ne:null}});
{
<.. other stuff went here..>
"displayed" : null
}
The problem disappears on Version 2.6.1:
> db.sourceListings.findOne();
{
<.. other stuff ..>
"displayed" : null
}
> db.sourceListings.findOne({displayed:{$ne:null}});
null
Probably was fixed somewhere in between these two versions.
I cannot seem to reproduce this. What version of Mongo are you using? (I am using 2.1.1-pre) Here are the steps that I took. The following is from the JS shell:
> db.users.save({
"_id" : 1,
"pic" : {
"id" : "4f1e1ab9cdf9dbaa160000be",
"status" : null
}
});
> db.users.save({
"_id" : 2,
"pic" : {
"id" : "4f1e28480eaf38193d00006e",
"status" : null
}
});
> db.users.save({
"_id" : 3,
"pic" : {
"id" : "4f1e28480eaf38193d00006e",
"status" : "Something"
}
});
> db.users.find({"pic.status":{$ne:null}}, {pic:1}).toArray()
[
{
"_id" : 3,
"pic" : {
"id" : "4f1e28480eaf38193d00006e",
"status" : "Something"
}
}
]
Only the document containing "pic.status":"Something" is returned.
My only thought is, are you absolutely certain that the value of (null) in the query is the same as what is saved in the documents? Were the documents saved using the JS shell, or were they saved using a driver in a different language? Theoretically, null, should be null, should be null, in any language, but I know that different languages represent "no value" differently. In python, for example, the value for "no value" is (None). (null) is not recognised in python.
In a python shell, I attempted to save a document with (null) as a value, but received an error:
In [13]: coll.save({"_id":5, "pic":{"id":5, "status":null}})
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
/Users/mbastien/mongodb-osx-x86_64-2.0.1/bin/<ipython-input-13-1ad232456c88> in <module>()
----> 1 coll.save({"_id":5, "pic":{"id":5, "status":null}})
NameError: name 'null' is not defined
I then inserted (with the Python shell) a status of 'null' ('null' being a string)
In [15]: coll.save({"_id":5, "pic":{"id":5, "status":'null'}})
Out[15]: 5
Not surprisingly, when I reran the query in the JS shell, this document was returned, because 'null' != null
> db.users.find({"pic.status":{$ne:null}}, {pic:1}).toArray()
[
{
"_id" : 3,
"pic" : {
"id" : "4f1e28480eaf38193d00006e",
"status" : "Something"
}
},
{
"_id" : 5,
"pic" : {
"status" : "null",
"id" : 5
}
}
]
Is this similar to what you are experiencing, or can you reproduce this 100% in the JS shell? Hopefully, we will be able to get to the root of this issue!
Use $nin with a single element in the array. It'll behave as you expect. KI with many of the people who use mongo.