Insert field with $currentDate to MongoDB collection in Meteor - javascript

Not sure how to use $currentDate when inserting a document into a MongoDB collection in Meteor.
Can this only be used in an update, not an insert? Would seem strange, but I don't see an alternative (other than using new Date instead).
Example
Stuff.insert({
owner: Meteor.userId(),
createdAt: ..., // how to create this field with $currentDate ?
theStuff: "Some of the good stuff"
})
Notes / Thoughts / TL,DR
Fields can't start with $ operators or, as far as I know, curly braces {}.
What's the point of having an operator that only works with updates, if that's indeed the case?
Why/when is $currentDate better than new Date?
One nice thing, if using Moment.js esp, is that $currentDate is entered in ISO 8601 format.
Is the answer to do some kind of upsert from the start? If so, could this have unintended consequences?

What's the point of having an operator that only works with updates, if that's indeed the case?
$currentDate is an update operator thus you can't use it with the collection.insert method. But when upsert is true it will create a new document when no document matches the query criteria. MongoDB operators tend to follow the Unix philosophy
Do One Thing and Do It Well
So each operator should perform only one task.
Why/when is $currentDate better than new Date?
First I would like to mention that new Date is a JavaScript Date instance.
$currentDate and new Date can be used when you want to update the value of a field to current date but with new Date you need to use another update operator for it to work. For example:
Using new Date
db.collection.update({ "name": "bar" }, { "$set": { "date": new Date() }})
Using $currentDate
db.collection.update({ "name": "bar"},
{ "$currentDate": { "date": { "$type": date }}}
)
Unlike $currentDate, new Date can be use with the insert method and value can be set to a particular if Date is call with more than on argument.

You can retrieve timestamp from autogenerated "_id" that is created within insert operation.
http://api.mongodb.com/java/current/org/bson/types/ObjectId.html
Just use the method : ObjectId.getTimestamp().
Timestamp granularity is in seconds.

It will become more simple if you will use autoValue in collection model
createdAt:
type: Date
autoValue: ->
if this.isInsert
return new Date
else if this.isUpsert
return $setOnInsert: new Date
else
this.unset()
It will automatically set date while insert or update the data into it

$currentDate when used in the $update construct can be used to insert fields if they do not pre-exist in the document.
Quoting documentation for Mongodb 3.4:
Behavior
If the field does not exist, $currentDate adds the field to a document.

Although I do totally appreciate that this design makes perfect sense, there is an argument, perhaps a bad one, that you want to set the updated_at field to something sensible when you insert a document. One reason that you might want to do this is to avoid always needing to query on two fields to get the last updated time. Like I say, this might be bad juju, but well there you go.
Anyway the best hack that I could come up with to do this is to perform an upsert that filters on not the empty filter. That guarantees that the upsert is always an insert.
Just a small comment on this to the MongoDB Devs. As someone who has been working with databases for more years than they care to remember, getting my head around how one is supposed to do timestamps correctly in MongoDB:
created_at => _id.Timestamp
updated_at => $currentDate()
has taken me far too long. Maybe that's my fault, it probably is, but it's something that I think most people probably want / need to do and as a concept it could be explained better. If you search around you will find a lot of bad / wrong information, because I'm pretty sure that this is the way to do it and ... well the internet is far from at consensus on this (although I am now).
I don't know, maybe it's a test. Maybe this is the first thing you ask someone when you are hiring a MongoDB developer: how do you do timestamps? Well, that's what I'd ask anyway because if you know you've probably learned most of the API by that stage.

Related

Firestore can not write date as collection name

I'm trying to write to Firestore all the prices from different stocks. Structure should look something like this (although this might not be the best fitted for it, still thinking of it as in SQL) :
const d1 = new Date();
const result = d1.getTime();
console.log('Epochtime',result);
database.collection("stock1").doc("exchange1").collection(date).doc('prices').set({"price":"price_value"})
Now the problem is that I can't create a collection with a name that's a variable that contains date. I tried all the different types of it and I presumed that epoch time should work, as this is a number like: 1636213439908. I always get the error: Value for argument "collectionPath" is not a valid resource path. Path must be a non-empty string. Although the exact same variable can be written as a value in a collection. So not sure what am I doing wrong here.
Document IDs in Firestore must be strings, so you'll have to convert the data to a string. While date.toString() will work, I highly recommend using a ISO-8601 format for the dates, such as date.toISOString(). These formats are designed to be both humanly readable and machine sortable.

Facebook Parse getting expired dates from table

I am working on a parse (Facebook) app. I have a table however I want to be able to get the expired events (aka events that occur after some date). What is the best way to do this. I didn't see a date documentation with Parse.
My thought from dynamo experience was to simply save it and compare the values but this is costly. Is there a more efficient way?
Any ideas / anyone done this?
Thanks!
Just use the greaterThan, greaterThanOrEqualTo, lessThan and lessThanOrEqualTo methods on Parse.Query, and pass in date objects.
I.e.
var query = new Parse.Query("Event");
query.lessThan("eventDate", new Date());
This query will get you all objects from the table "Event", whose column "eventDate" (a Date column) contains a date that is before the current date.

A good way to implement a string tokenizer ( or use one that's already established )

Found myself in a situation where I was making one of two rookie mistakes:
Writing code that I should get out of a library
Writing super complex code that could be greatly simplified using better patterning
What I'm trying to do is pretty simple, I need to send instructions to some JavaScript code that prints fields from an object to the page. Things started out fine, the following string:
message, tags, date
Easily instructed the code to get these elements from the object using
field_array = instruction_string.split(',')
obj['message'], obj['tags'], obj['date']
Then I realized that I wanted to modify that date field to reflect the time zone I was in. Enabling the string to carry special instructions for a field added a little complexity with regex, but still wasn't too complicated:
message, tags, date(GMT-5)
Using the code:
var special_instruction = /\(.*\)/ig.exec('date(GMT-5)')[2]
RESULT: special_instruction = 'GMT-5'
I realized that I was getting in over my head when I realized that I also wanted to tell the output to adjust the date so that it reflects the time delta since right now instead of printing the actual date:
message, tags, date(GMT-5_)(SINCE_NOW)
The regex that I wrote didn't work:
var special_instruction = /\((.*)\)/ig.exec('last_updated(GMT-5)(since_now)')
RESULT: special_instruction = 'GMT-5)(since_now'
Although there is probably a way to fix the regex, this indicates that I should be using a tool or established pattern to do this instead of writing custom code off the cusp and screwing around with it for way too long.
Are you sure you want to use strings and regular expressions for this?
An alternative would be to use an array and objects for defining the fields that should be printed.
Something like this:
var fields = [{
name: 'message'
}, {
name: 'tags'
}, {
name: 'date',
timezone: 'GMT-5',
since: new Date() // now
}];
For getting the values from that sure be printed you can iterate over the array and look for the name field. If you found an object with name date you can look for additional properties. You could also add new properties very easily.

Storing dynamic dates in javascript

I wish to store if a specific date is loaded via Javascript. How this boolean is saved/accessed has no difference, however I'm not sure as to what the best solution is performance-wise.
I could know I could store it like this and loop through each object, however I guess this wouldn't really be efficient.
var loaded = { {d:23, m:11, y:2012}, {d:24, m:11, y:2012} };
Another idea I have is to store this in an array, like so:
loaded[2012][11][23] = true;
But I'm sure there are better ways to accomplish this, so I'd appreciate any guidance
Unless you have to list available years, available months or available days, you could always use an Object as a dictionary for storing dates as UNIX timestamp numbers (which you can convert to and from Date objects) or "YYYYMMDD" strings.

jQuery.param() - doesn't serialize javascript Date objects?

jQuery.param({foo: 1}); // => "foo=1" - SUCCESS!
jQuery.param({bar: new Date()}); // => "" - OUCH!
There is no problem with encodeURIComponent(new Date()), which is what I would have thought param is calling for each member.
Also, explicitly using "traditional" param (e.g. jQuery.param(xxx, true)) DOES serialize the date, but alas, that isn't of much help since my data structure isn't flat.
Is this because typeof(Date) == "object" and param tries to descend into it to find scalar values?
How might one realistically serialize an object that happens to have Date's in it for $.post() etc.?
You're probably going to want the date transformed into a string, since that's what it's going to have to be on the wire anyway.
$.param({bar: new Date().toString()});
Now you may want it formatted in some particular way so that your server gets something it can parse. I think that the datejs library has support for formatting, or you could roll your own by picking out pieces of the date with getDate(), getMonth(), getYear() etc.
If you work with Microsoft products on the server side you should take in consideration, that Microsoft serialize Date as a number of milliseconds since UTC, so as a number. To be more exact, the serialization string look like /Date(utcDate)/, where utcDate date is this number. Because JSON supports the backslash as an escape character you should use code like following to serialize a Date object myDate:
"\/Date(" + Date.UTC(myDate.getUTCFullYear(), myDate.getUTCMonth(),
myDate.getUTCDate(), myDate.getUTCHours(),
myDate.getUTCMinutes(), myDate.getUTCSeconds(),
myDate.getUTCMilliseconds()) + ")\/"
I think this is a jQuery bug in the following context:
jQuery 1.4.2 (1.3.2 works)
new methods added into Date.prototype

Categories