Incrementing a date in javascript, in order to update MongoDB - javascript

In MongoDB collection I have 3 objects. I need to update one variable (date type) in each object. The main task is to increment the date of the objects. For example: all objects have the same variable:
"Time1" : ISODate("2016-01-12T21:37:46.738Z")
My problem is to update the first object with the current date, manually I do it in this way:
$db.getCollection('my.data')({'_id':ObjectId("52e637fca92cf1ec6a73c1e8")}, {$currentDate: {Time1: true}})
The next is to increase the date of the second object by 1 day, I mean to update it with tomorrow date. I couldn't do it through the shell, because $inc doesn't work with Date type.
So, I am lost with javascript
I found how to get it with java script but I don't know how to collect all if this in one script.
var tomorrow = new Date();
tomorrow.setDate(today.getDate()+1);
Thank you for your help.

You could use the $set operator for the other fields, together the the $currentDate operator all within the update object:
var tomorrow = new Date();
tomorrow.setDate(tomorrow.getDate()+1);
var dayAfterTomorrow = new Date();
dayAfterTomorrow.setDate(dayAfterTomorrow.getDate()+2);
db.getCollection("my.data").update(
{ "_id": ObjectId("52e637fca92cf1ec6a73c1e8") },
{
"$currentDate": { "Time1": true },
"$set": {
"Time2": tomorrow,
"Time3": dayAfterTomorrow
}
}
)

Related

How to link multiple children item to a single parent item?

I have a list of dates with properties and method I create with :
New CalendarDate('2018-XX-XX')
And for each date, I have a list of hours. I would like each of my hour to reference one single date.
At the moment, the solution I came from seems... inadequate, and I would like to understand the proper way to do it. So for each hour I create a new instance of Hour and pass the newly created date. I.E :
Class CalendarDate {
dateString: string
constructor(date: string) {
this.dateString = date
}
getDate() {
return this.dateString
}
}
Class CalendarHour {
date: CalendarDate
constructor(date: CalendarDate) {
this.date = date
}
}
let date1 = new CalendarDate('2018-11-11')
let hour1 = new CalendarHour(date1)
let hour2 = new CalendarHour(date1)
I want to avoid creating a new CalendarDate for every CalendarHour, but I'd rather like each CalendarHour to refer to the same CalendarDate object. What would be a better approach than the one I came up with ?

convert time string to date object javascript

I'm trying to plot D3 timeseries by referring :
http://mcaule.github.io/d3-timeseries/
which takes Date in this format : 'new Date('2013-01-01')
Now, I have following array:
var data =[{
"time": "2017-06-23T23:37:20-07:00",
"value": 25.189767114257663
},
{
"time": "2017-06-23T23:37:30-07:00",
"value": 24.637318860009692
},
{
"time": "2017-06-23T23:37:40-07:00",
"value": 24.896462306379043
},
{
"time": "2017-06-23T23:37:50-07:00",
"value": 24.348000192323468
}]
I need to give this array as input to the d3 timeseries function. But I'm unable to plot anything as above time is not a Date object. How do I append or convert that time string to date object. Because I absolutely need to have that new Date thing otherwise that function is not at all executing.
I tried to convert time into date object using:
data.map(function(ele) {
ele.time = new Date(ele.time);
});
So, this thing appended Zone to all the times. When I tried to give this array as input to d3 function, it doesn't work.
You can map the timestamp to a date object by iterating over data and assigning a new field called date.
data.forEach(function(elem, index, arr) {
arr[index]['date'] = new Date(
arr[index]['timestamp'].split('T')[0]);
});
Pretty basic string splitting, and there are probably more elegant solutions, but here's a start.

Add time to $currentDate in $set statement

I am trying to perform 2 operations in one findOneAndUpdate():
Update date in one field lastUpdatedTimestamp, set it to current date (this one works fine in my statement),
Update date in other field expiryTimestamp, by adding 1 day to $currentDate (I couldn't find a way to achieve it so I'm trying to $add 1 day to the the value read from the above field lastUpdatedTimestamp) - (I can't make this one work).
findOneAndUpdate(
{"_id":123},
{ $currentDate: {"lastUpdatedTimestamp":true}, $set: {"expiryTimestamp": {$add: ["$lastUpdatedTimestamp", 24*60*60000]}}}
)
Here's the error I'm receiving:
{ "ok" : 0.0, "errmsg" : "The dollar ($) prefixed field '$add' in 'expiryTimestamp.$add' is not valid for storage.", "code" : 52 }
Is it even possible? I'd appreciate your help.
You can use the setDate() method to set the "expiryTimestamp" value.
db.collection.updateOne(
{ "_id": 123 },
{ "$set": {
"lastUpdatedTimestamp": new Date(),
"expiryTimestamp": new Date().setDate(new Date().getDate() + 1)
}}
)
You don't need to use findOneAndUpdate unless you want to return the new or old document.
The marked answer is wrong in the sense that using new Date() will not use database timestamp which is important if your server and database hosted on different region and also count network time for sending data. To correctly do this, use $currentDate like this:
db.collection.findOneAndUpdate({_id: 123 }, {
$set: { /** update doc here **/ },
$currentDate: { lastUpdatedTimestamp: true}
});
Similarly using updateOne
db.collection.updateOne({_id: 123 }, {
$set: { /** update doc here **/ },
$currentDate: { lastUpdatedTimestamp: true}
});

MongoDB: how to update n records based on ObjectID

I've created a Collection containing 1 million documents, and I'm trying to select 50000 of these records based on the ObjectID, and update one of the values (i'm working in Mongo shell, running on Ubuntu).
Is it possible to define a 50000 document range? It doesn't matter which documents are included in the 50000 range, I simply want to ringfence a definite number of records and run an update operation using the primary id so that I can measure the performance time.
The code I've tried to run doesn't work:
use Assignment
var _start = new Date()
db.FlightsDate.update({$set:{Airtime: 8888}}).limit(50000).hint({_id:1});
var _end = new Date();
print("Time to Bulk Update AirTime key for 50000 documents… " + ((_end _start)/1000));
...i'm gathering that MongoDB needs me to include a query in the command to specify which docs are to be updated (I now understand from reading other posts that .limit won't constrain the number of records than an .update writes to).
Please can anyone advise a method that'll enable me to define the number of records to be updated?
Grateful for advice.
R,
Jon
If you are simply looking for a "range" that covers 50,000 of the documents in the collection then your best approach is to query and find the "starting" and "ending" documents of your range first. Then apply that "range" specification to your update.
var start_id = db.FlightsDate.find({}).limit(1).toArray()[0]._id;
var end_id = db.FlightsDate.find({}).skip(49999).limit(1).toArray()[0]._id;
var _start = new Date();
db.FlightsDate.update(
{ "_id": { "$gte": start_id, "$lte": end_id } },
{ "$set"; { "Airtime": 8888 } },
{ "multi": true }
);
var _end = new Date();
( _end - _start )/1000;
If you then wanted the next 50,000 in an additional range then :
var start_id = db.FlightsDate.find(
{ "_id": { "$gt": end_id } }
).limit(1).toArray()[0]._id;
var end_id = db.FlightsDate.find(
{ "_id": { "$gt": end_id } }
).skip(49999).limit(1).toArray()[0]._id;
And do it all again.
The point is you need to know where to "start" and when to "end" within a range to limit your update to just 50,000 documents without any other criteria to do so.
Also note the usage of "multi" in the update method there. By default, .update() does not "update" any more than one document, essentially being the first match. So what you mean to do is update "all documents in the range" and that is why you need to apply "multi" here.

global variables in javascript / mongodb / mapreduce

I know this has been asked countless times on the internet but I can't figure out what's going on here and I have been banging my head against walls for hours now.
This works :
in myscript.js :
obj = 'hello';
var f = function() {
printjson('obj=' + obj);
}
f();
$ mongo myscript.js
obj=hello
This doesn't work :
date1 = "2013-09-03T00:00:00Z";
date2 = "2013-09-04T00:00:00Z";
var mapIntensities = function() {
emit(this.unit, this.intensity);
};
var reduceIntensities = function(unit, intensities) {
return {date: date1, "unit": unit, "intensity": Array.sum(intensities)};
};
db.units.mapReduce(mapIntensities, reduceIntensities, {out: "aggregate_intensities", query: {"DATE": {$gte: ISODate(date1), $lt: ISODate(date2)}}})
Why is that ? The problem occurs in the reduce() function (if just there I replace date1 with the hardcoded value it works)
Is it specific to mongodb's way to do mapreduce ? (as the working example suggests)
Because date1 is never defined within the Map Reduce itself, it is only ever used here:
return {date: date1, "unit": unit, "intensity": Array.sum(intensities)};
And then you do not define a variable to input at all into the actual call of the Map Reduce.
The Map Reduce runs within a self contained JavaScript (spidermonkey or v8) envo within MongoDB, not in the mongo console as I assume you are doing there.
You need to use the scope param: http://docs.mongodb.org/manual/reference/command/mapReduce/#dbcmd.mapReduce to send in date1

Categories

Resources