How can I update my model in a sailsjs Controller like mongodb updates: a complete document replacement - mongodb

For my purposes, I'd like sailjs's
Collection.update(id, {params}, cb)
to work like mongodb's update, with the entire model getting swapped out. Is there a way to do this through in a sailsjs Controller?
For example: if I have a model that looks like
{ _id: "123...", good: true, bad: false, createdAt: dt, updatedAt: dt }
and my {params} are
{ _id: "123...", good: false }
I'd like the resulting model to be
{ _id: "123...", good: false, createdAt: dt, updatedAt: newdt }

Related

Getting directly an array from a mongoose model

I'm trying to query directly to an array inside of an mongoose document, but for the moment i have couldn't.
The document example:
{
_id:62141a799b646c7926fcfa9c
firstname:"firstname"
lastname:"lastname"
username:"username"
phone:"0000-0000000"
email:"Example#mail.com"
email_verified_at:null
password:"$2a$10$LUATvtyPmlojHVdCkxP/QO9UUzQgOoGCW6xyx8YPUZkt5l7j6kHxK"
remember_token:null
deleted_at:null
created_at:2022-02-21T23:04:25.097+00:00
updated_at:2022-02-21T23:04:25.097+00:00
notes: [
"621954b8f073154099b92fca"
"62142c426ca950e33baa1302"
]
I have a query that works but i think that isn't the most optimal approach, altough i could be wrong.
I want to get something like this:
[
"621954b8f073154099b92fca"
"62142c426ca950e33baa1302"
]
or populated:
[
{
_id: new ObjectId("621954b8f073154099b92fca"),
user: new ObjectId("62141a799b646c7926fcfa9c"),
type: new ObjectId("62076ce385b4eea8c5aeb8ba"),
title: 'qwasdasd',
content: '',
created_at: 2022-02-25T22:14:16.515Z,
updated_at: 2022-02-25T22:14:16.515Z
},
{
_id: new ObjectId("62142c426ca950e33baa1302"),
user: new ObjectId("62141a799b646c7926fcfa9c"),
type: new ObjectId("62076ce385b4eea8c5aeb8ba"),
title: 'qwasdasd',
content: '',
created_at: 2022-02-25T22:14:16.515Z,
updated_at: 2022-02-25T22:14:16.515Z
}
]
And even if i need to find an specific field, search it, but with the query:
const notes = await collection.findOne({ _id: '62141a799b646c7926fcfa9c', notes: { _id: '621954b8f073154099b92fca' } }, { 'notes.$._id': true });
i have this rersult:
{
_id: new ObjectId("62141a799b646c7926fcfa9c"),
notes: [
"621954b8f073154099b92fca"
]
}
or populated:
{
_id: new ObjectId("62141a799b646c7926fcfa9c"),
notes: [
{
_id: new ObjectId("621954b8f073154099b92fca"),
user: new ObjectId("62141a799b646c7926fcfa9c"),
type: new ObjectId("62076ce385b4eea8c5aeb8ba"),
title: 'qwasdasd',
content: '',
created_at: 2022-02-25T22:14:16.515Z,
updated_at: 2022-02-25T22:14:16.515Z
}
]
}
And i know that i can reach it filtering the ObjectId from user with '-_id notes.$._id' instead of { 'notes.$._id': true } and then destructuring the main object with a const { notes } resulting in this code:
const { notes } = await collection.findOne({ _id: '62141a799b646c7926fcfa9c', notes: { _id: '621954b8f073154099b92fca' } }, '-_id notes.$._id' );
But, it's the best approach to do this? Could i do it in different way being able to take advantage of findOne options like, skip, etc...?
PD: If there's some error it's because it's not the original code, i have modified it because in original code there're many abstractions.
Thanks in advance.

How to relation the child document in mongodb?

How can I refer a table to a child document in another table in mongodb?
For example, a video can only be added to the parent category or to a child category. Like video categorization sysytem of udemy website. I tried the mongodb refPath but I can't use dynamically at this system.
How can I do this query?
My video schema:
...
const VideoSchema = new mongoose.Schema(
{
category_ids: [
{
model_id: {
type: mongoose.Schema.Types.ObjectId,
refPath: 'category_ids.model_name'
},
model_name: {
type: String,
required: true,
enum: ['category', 'subcategory']
}
}
],
...
}
)
module.exports = restful.model('video', VideoSchema)
I solved my problem.
When I added these two schemas, the query worked.
require('../models/category')
require('../models/subcategory')
And then run the find method with populate.
// ...
require('../models/category')
require('../models/subcategory')
Video.find({
user_id: req.body.user_id
})
.populate({
path: 'category_ids.model_id'
})
.exec()
.then((videos) => {
console.log(videos)
})
// ...

Insert default values not working mongodb

I am using mongoose version 5.2.5 and here is the sample model of my order
....
let PlaceOrderSchema = new mongoose.Schema({
any: {}
}, { strict: false },
{ timestamps: { updatedAt: 'last_updated', createdAt: 'created' });
I am using the above model in main script with mongoose save and findOneAndUpdate.
In our production system , we are seeing many document that does not have last_updated key missing in the save document.
Here are sample code of the mongoose save method and findOneAndUpdate in our main script.We are seeing some of the documents have updated_at keys while very few of them does not have it while saving the document
let orderModel = require('./orderModel');
let newOrder = {
order_no: 1234
};
//save usage code
(new Order(newOrder).save({lean: true}, ()=> {
//do...something
}));
//findOneAndUpdate usage Code
let orderNo = 123
OrderModel.findOneAndUpdate({ order_no: orderNo },
{
$set: { items: [{product_id: 'abc', quantity: 1}] },
},
{ new: true, upsert: true },
(err, res) => {
//do_something
});
Can any one share why we have few documents are getting saved without updated_at?
You need to use option setDefaultsOnInsert: true during the update operation.
Docs
By default, mongoose only applies defaults when you create a new
document. It will not set defaults if you use update() and
findOneAndUpdate(). However, mongoose 4.x lets you opt-in to this
behavior using the setDefaultsOnInsert option.
OrderModel.findOneAndUpdate(
{ order_no: orderNo },
{ $set: { items: [{ product_id: "abc", quantity: 1 }] }},
{ new: true, upsert: true, setDefaultsOnInsert: true }
)

Mongoose findOneAndUpdate not saving

I have the a mongoose model I'm trying to update right now using the .findOneAndUpdate method with the below code:
MyModel.findOneAndUpdate({ _id: "xxxxx", userId: "xxxxx" }, { $set: { completion:"xxxx", date: "xxxxx" } }, { new: true }, function(err, doc) {
if(err) {
return res.json({success: false, message: err.message});
}
res.json({success: true, message: 'success'});
});
When I log doc, it returns the updated model, but the model is not being saved to the database. Any thoughts on this would be greatly appreciated.
Model Code:
var MyModel = new Schema({
name: {
type: String,
required: true
},
date: {
type: Date,
required: true
},
userId: {
type: String,
required: true
},
completion: {
type: Boolean,
required: true
}
});
There are few issues as per your posted code:
1) MyModel is a Schema object, you will have to create a Model object like this -
var model = mongoose.Model('modelName', MyModel); // where MyModel is a Schema object
Then using the above model object you can run your findOneAndUpdate, like in your code (like model.findOneAndUpdate).
2) Secondly, in the MyModel Schema you have not given the collection name. You can put it in the options object which comes after the schema object argument. So you should put:
var MyModel = new Schema({schema object...}, {collection: 'mongodbCollectionName'});
If you do not give above option,mongoose would create a default collection using the model name.
I believe if (1) is not there, (2) is most likely causing the issue in your case.

Using mongoose timestamps option does not create properties

I may be missing something obvious, but have read to docs.I had an existing collection. Using Robo3T, I dropped it. In my script, running out of Node, I have defined the schema adding timestamps option as shown below. I run my app. The collection is created. However, there are no timestamps when I view via Robo. Everything else is as I expect. The indices are created. The fields are populated.
I expected two additional properties: createdAt and updatedAt.
I am using mongoose 5.2.7.
const categorySchema = mongoose.Schema(
{
value: String,
recordName: String,
sourceId: Number,
targetId: Number,
requestParameters: Object,
magentoResponse: Object
},
{
autoIndex: true
},
{
timestamps: true
}
);
categorySchema.index({sourceId: 1}, {unique: true});
categorySchema.index({targetId: 1, recordName: 1}, {unique: true});
Oh! I was being an idiot. autoIndex and timestamps should be in the same block. I was being an idiot!
It should have been:
const categorySchema = mongoose.Schema(
{
value: String,
recordName: String,
sourceId: Number,
targetId: Number,
requestParameters: Object,
magentoResponse: Object
},
{
autoIndex: true,
timestamps: true
}
);
categorySchema.index({sourceId: 1}, {unique: true});
categorySchema.index({targetId: 1, recordName: 1}, {unique: true});
How did you re-create those records? If they did not go though mongoose (but via mongoDB client/cli) they would not have those fields. These are mongoose specific.
And are created when you create a new Model and save it:
var thingSchema = new Schema({..}, { timestamps: { createdAt: 'created_at' } });
var Thing = mongoose.model('Thing', thingSchema);
var thing = new Thing();
thing.save(); // `created_at` & `updatedAt` will be included