I am using mongodb in my application to store data through nodejs . I have created a schema for a collection (to make it here easy I will call that collection register ) .Below is the structure of the collection' s schema .
const register_schema = new Schema(
{
arrived_at: { type: String }, // time of arrival
gone_at: { type: String } // time of departure
}
);
I want just to save time in the arrived_at and gone_at fields in the format of 'HH-MM-SS'. Is it possible to store such data in mongodb?
There is no fine datatype for time handling or for adding specific time in mongodb schema except the timestamp. For adding time, just use string to specify the timing you want to add.
Related
I'm using MongoDB and Mongoose to use a specific schema.
To automatically process data within MongoDB when it is stored, it has the following schema structure:
{
...
createdAt : {
type : Date,
default : Date.now
}
}
Using the schema above, run Mongoose's create, updateOne, and look at the createdAt value stored through MongoDB Compass, the daily time range is set as follows.
2023-01-20T15:00:00.000+00:00 ~ 2023-01-21T14:59:59.999+00:00
In the case of MongoDB, I understand that you cannot set up a separate timezone and that you need to process the time in the Application Layer.
In addition, DB and API servers that use DB are using the "Etc/UTC(UTC+0)" time zone.
In order to solve the above problem, the range of the day was specified as follows to specify a specific time, but the data could not be viewed normally when finding.
const beginDate = moment.utc().startOf('day').toDate(); // 2023-01-21T00:00:00.000Z
const endDate = moment.utc().endOf('day').toDate(); // 2023-01-21T23:59:59.999Z
But is the reason why it is saved like the above time range is because it calls API server in Korea (UTC+9)?
Is createdAt created by the mongoose timestamps feature unique or not if we create multiple documents using mongoose?
No, there is no enforcement of uniqueness enforced at the DB level for these fields.
From a usage perspective we can look at mongoose source code to see how these fields are created:
const createdAt = handleTimestampOption(timestamps, 'createdAt');
const updatedAt = handleTimestampOption(timestamps, 'updatedAt');
const currentTime = timestamps != null && timestamps.hasOwnProperty('currentTime') ?
timestamps.currentTime :
null;
const schemaAdditions = {};
schema.$timestamps = { createdAt: createdAt, updatedAt: updatedAt };
if (updatedAt && !schema.paths[updatedAt]) {
schemaAdditions[updatedAt] = Date;
}
So we don't need to follow the entire flow to understand this is created in memory. Basically when you create a new document the schema creates these two defaulted fields if you have timestamps enabled. Which means from a practical usage perspective it's unlikely for you to get 2 identical timestamps if you're only running a single app.
If you run multiple processes with multiple updates then this case becomes more likely.
Im learning mongodb and I have the following question: In one Schema, I have a reference to another model - Im storing id's of books. I have a books model where I have a reference to other books - saving their id's.
The id's of 'similarBooks' I will insert manually. But id's of the books will be always in the format of
ObjectId("1234").
If user clicks on the name of book a query will be made - findById. However the id's I manually inserted are just strings, not ObjectId("id") so it wouldnt find the book. What is the best way to handle this? Do I then in my query take the id (the one thats just a string) and convert it to ObjectId("id") or do I not just insert manually the id as string but already convert to ObjectId. If so how? So far I just been adding data for this type of models in 3t studio.
Same question is for writing tests. If i have ids stored as strings, do I convert to the ObjectId ?
Thank you!
const bookSchema = new mongoose.Schema({
title: {
type: String,
required: true
},
similarBooks: {
name: {
type: [String] //would be only 2
},
id: {
type: [String] //would be only 2
}
}
...
})
There is an answer on the advantage of saving Id as ObjectId instead of string here. Mainly it saves on space.
MongoDb: Benefit of using ObjectID vs a string containing an Id?
So to answer you question, i would always convert that String id to ObjectId before adding it to your similarbooks array.
I've run into problem. I made field in my Mongoose schema with type "Date":
...
timeOfPassingQuestion: Date,
...
Now, I want to pass current time in hours, minutes, seconds and miliseconds and save it into that field. How should I format my Node variable so I can pass it without errors?
Edit: Also, I forgot to say that I wanna later see how much time user spent answering question by subtracting current time and time that I pulled from DB, timeOfPassingQuestion field.
This is the syntax to create a schema that supports a date field:
// Schema
{ //...
someDate: Date,
}
// date object that you can use whenever you decide to set it
var dateObj = new Date();
This will create a JavaScript date object that you can then pass into your Mongoose object for the date field.
Or, if you will always want it on creation, put it directly in your mongoose schema
{ //...
createdDate: { type: Date, default: Date.now },
}
In order to compare the time in the future, I suggest you use moment.js, then you can query the time difference like so:
moment(Model.createdDate).fromNow();
Sources:
Mongoose Schema
Moment.js fromNow
I have the following schema in my Node js / express app where each warehouse can optionally have a parent warehouse. I wrote the code to save warehouse, but can't figure out how to retrieve any warehouse (which has a parent) and get its parent warehouse name...so was wondering if there is any way I can do that in one call? Thanks
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var warehouseSchema = new Schema({
name: { type: String, required: true },
parentID: { type: String, ref: 'Warehouse' }
});
module.exports = mongoose.model('Warehouse', warehouseSchema);
Just as Philipp said, you can't do it with a single MongoDB auery.
But you can do it with single Mongoose command, using its Query Population feature:
Warehouse.findById(warehouse_id).populate('parentID').exec(function(err, doc) {
if (err) {
// something get wrong
} else {
// doc.parentID is a parrent Warehouse here
}
})
Internally, Mongoose will make two separate queries to MongoDB (one for the child document, and then another for its parent), bu for you it'll look like a single command.
MongoDB can't do JOINs on the database. As long as the parent is a reference in the warehouse object, you can not retrieve both with one query. You first have to query the warehouse(s) and then resolve the reference(s) with a second query.
To avoid the second query you might want to look into embedding the required information about the parent-document in the child-document. Duplicate information in MongoDB isn't as abnormal as in a relational database.