Storing converted dates in MongoDB [duplicate] - node.js

This question already has answers here:
Store date in MongoDB without considering the timezone
(2 answers)
Closed 4 years ago.
I was working on a project and since it is the first one, I didn't know about Mongo storing everything in UTC until I noticed that birthdates were being stored at day X-1 23:00:00 instead of day X 00:00 as it should. I've tried using moment and converting the date to my timezone before storing it but Mongo ignores it.
const bdate = moment.tz(body.birthdate, "YYYY-MM-DD", "Europe/Lisbon").format();
On console it shows:
1998-10-20T00:00:00+01:00
On the database it shows: "1998-10-19T23:00:00.000Z"
What can I do to be able to store the data in my local timezone or force MongoDB to show local timezone dates instead?
I've seen solutions using $project to convert into the local timezone but I'd like to get the entire converted date and not just hour/day/month.

From mongo docs seems like you can't https://docs.mongodb.com/manual/tutorial/model-time-data/
They recommend you convert it application side.
I think you should consider how you're going to use the date and how you're going to index the collection.
For example, if your goal is to send the user a notification "Happy birthday" on their birthday at a specific time of day in their local time zone, you might want to bake that time zone shift into what you store in Mongo. That way you can index on the birthdate field, and get all the users you need to notify by querying like db.users.find({ birthdate: ). Obviously if the user physically moved time zones this would break (you'd have to update that if they moved). Alternatively you could store their birthday + local timezone as separate fields, but that would make querying it much more complicated.

Related

Merge data from local database to remote database of Mongodb

I have a remote central database(MongoDb) that must contain all records coming from using a application by many clients!
The application save data in local collection, then should save data in remote database !
we’re good until now… the problem comes when there is no internet, we go in offline mode.
So lets suppose that we have a remote MongoDb Central database and 2 clients : client A and client B => local database A + local database B
(the two databases are independent).
We are offline ! I have created a document doc1 in the Local DB-A and document doc2 in the Local DB-B .
Online mode is active so the db A must push the doc1 in DB central also the db B must push the doc2 in DB central.
I am using MEAN stack application.
I have checked ChangeStream, but not sure during network break how it will work..
Anyhelp will be much appreciated.
I am not sure about the realm and change-stream, you need to brainstorm do your own logic as per your requirement,
I had the same situation and asked in the MongoDB forum in this topic, but got a suggestion to implement change-stream, I tried but was not worked for me,
After that, I developed my own logic using NodeJS, ExpressJS, and MongoDB driver APIs to sync data from local to live and wise versa,
If I explain to you in simple steps and examples:
added a timestamp property that is created timestamp for every collection's documents, _id objectId will also work
ex: createdAt: ISODate("")
created 2 collections for settings in the local server (one for local to live sync and second for live to local sync), that store the db+collection name, timestamp property that is the last sync document's timestamp
ex: dbName.live_to_local_settings collection
{
"db_collection": "dbName.collectionName",
"syncProperty": "createdAt",
"lastSync": ISODate("")
},
...
created 2 scripts in local server: (both will execute as provided interval)
live to local sync:
loop dbName.live_to_local_settings collection documents and do the below steps for each collection
query to live collection (live."dbName.collectionName") and check is createdAt >= settings.lastSync and sort by createdAt in ascending order
query to local collection (local."dbName.collectionName") and check only above steps found documents by _id { $in: _ids }
loop the live collections found documents and do the below steps:
insert document in the local collection (local."dbName.collectionName") if it not exists in local
update the document if _id exists in local, there are 3 conditions:
ignore the update if both dates local.createdAt == live.createdAt are equal
check if live.createdAt < local.createdAt then merges both documents but the primary consideration is the local document because the createdAt is latest, and after merge replace that whole document in both the places local and live collections using replace query
check else if local.createdAt < live.createdAt then merges both documents but the primary consideration is the live document because the createdAt is latest, and after merge replace that whole document in both the places local and live collections using replace query
update lastSync date in dbName.live_to_local_settings collection, that is document's createdAt timestamp
local to live sync:
the above steps would be the same but you need to change it query location wise versa
This looks complex but, works perfectly with less internet connectivity, and resumes when the internet comes back!

How to get #servestamp firestore after add new Document

I add some data to firestore which contain #serverstamp, but after I add data , I need to get #serverstamp for other progress
If you're using server side generated timestamps you'll need to query the created document to read the actual timestamp value. Nonetheless, if you need the timestamp maybe it would be more practical to generate the timestamp client side, so the document read isn't needed.

How to automatically update date fields in mongoDB collection on insert/update documents?

I'm using MongoDB v3.6.3 with PyMongo.
Here's my document structure:
{
"process_id": number,
"created_dttm": date,
"updated_dttm": date
}
I want to do two things:
Whenever a new document is inserted, created_dttm and updated_dttm should have the current system date.
Whenever an existing document is updated, updated_dttm should be updated to the current system date at that time
I have done this using MongoEngine Models by overriding the save() and update() methods .
Is there any other way to do this using PyMongo other than explicitly handling this programatically while insert/update?
Unfortunately this doesn't come out of the box from mongodb/pymongo. The only thing you get is if you use ObjectId's as primary keys for your documents, you can extract the timestamp from it with
oid = ObjectId()
oid.generation_time # is a datetime.datetime
For the update timestamps, you'll need to handle that in your application code. There is usually 2 ways for doing this, either you emit & store audit events in a separate collection, either you wrap your update method and modify a last_update_timestamp every time it is called.

Table storage design for querying with a value within a range

I am looking at using a Table Storage, like Azure or Google or Apache HBase type for storing entities/rows but I could not find any help online for my usage pattern. It goes like this:
Entity has an ID or key, say "UserId"
Date value like "StartedUsingProduct"
Date value like "StoppedUsingProduct"
The queries will mostly be of type "At date T, find all users who were using the product". Note that the same UserId will have many (thousands) of start/stop pairs.
In the Azure case,
- PartitionKey would be UserID
- RowKey "StartedUsingProduct"
but then I can't find a decent way to query without going through a full partition scan.
In the Google case, following their recommendation,
- key would be like "UserID_StartUsingProduct",
and I get the same problem when I have to retrieve a substantial amount of rows and then filter out using the second property.
Has anyone some insights on how to attack this particular usage pattern?
Assuming a very simple entity design considering just these three custom attributes:
UserId
Action - Would indicate either start or stop
DateTime
So when a user starts using the product, you insert an entity for that user with Action = start and DateTime = current date/time. Likewise when a user stops using the product, you insert an entity for that user with Action = stop and DateTime = current date/time.
The pattern that you will have to use is store multiple records for a single activity.
This is needed because you could either be querying on a date (like you mentioned above) or querying on a user e.g. tell me how many times this user has started/stopped using the product.
1st Entity will have PartitionKey = UserId and RowKey = Current Date/Time. You can store the current date/time in form of ticks converted to string using something like DateTimeValue.Ticks.ToString("d20"). This pattern will ensure that you will be able to query activity by the user. You would specify the query as PartitionKey eq UserId and you will get all the records for that user. If you're interested in getting the latest activities first, you could use reverse ticks in RowKey using something like (DateTime.MaxValue.Ticks - DateTimeValue.Ticks).ToString("d20"). This will ensure that the latest records are prepended instead of appended.
2nd Entity will have PartitionKey = DateTimeValue.Date and RowKey = UserId. If you think that a user would start/stop using the software more than one time in a day, you would want to append the date time value in RowKey as well using something like RowKey = UserId|DateTimeValue. This will ensure that multiple start/stop activities for a user in a day can be logged without overwriting the previous activity for that user on that day. Now you can do a query on PartitionKey and that will tell you exactly what all users started/stopped using the product.

set only time in mongoose schema

How to set only time in mongoose schema ?
like we can do in sequelize schema
startTime: DataTypes.TIME,
endTime: DataTypes.TIME
is their any way in mongoose to set time in mongoose schema??
It's simple Date and nothing else like this --> startTime : Date
Here is the documentation for all available data types for mongoose: http://mongoosejs.com/docs/schematypes.html
In case you only require the time of the date you can use a getters to achieve that: http://mongoosejs.com/docs/2.7.x/docs/getters-setters.html
I've tried achieving the same thing before but failed.
The best solution that was I able to come up with was to just add the time during the insert to the database and not when creating the schema.
This way you can use datetime.toLocaleTimeString(); or moment.js to just add the time without the date etc.
I'm afraid there is no mongoose schema type to store a time like you can do in SQL.
I have stored a time as a Date in one of my project, keeping just the time part of that date. It works more or less.
And maybe MongoDB $hour and $minute aggregation can help.
But it is not a very elegant solution.
Another possibility is to store your time as separate Number (hours, minutes, seconds).
Best method I found so far is to store it as a String, as mentioned in this answer.
Maybe you can go further into this idea and create your own custom schema Time type.

Resources