Im having mongo(mongoose) collection called "asserts" and "users".
Having list of documents in "asserts" collection.
Now while adding a user I need to select multiple "asserts". So need to set "ref" to asserts collection.
Below is my modal
asserts_list: {
type: [Schema.Types.ObjectId],
ref: "asserts" },
POST operation is working fine (i.e) I can add multiple object IDs in Mongoose in array. But while performing list using AppComp.find({}) with populate, asserts_list is returning empty array([]).
Help me to retrieve array of object ids in find({}) using nodejs.
You need to define properly
asserts_list: [{
type: Schema.Types.ObjectId,
ref: "asserts" }],
and then use populate function
Related
Problem
I have an ObjectId saved in a field -incomingFriendRequests- and I want to move it to another field -friends-.
Is there a better way to do this than to remove it from receivedFriendRequests and then do an findOneAndUpdate to add it to friends? I feel like this can be accomplished with one database call instead of two.
Code
Mongoose Model:
const userSchema = mongoose.Schema({
friends: [{
type: mongoose.Schema.Types.ObjectId, ref: 'User', require: false
}],
incomingFriendRequests:[{
type: mongoose.Schema.Types.ObjectId, ref: 'User', require: false
}],
online: {type: Boolean, require: true}
});
It is not possible in a single query you need to first perform $pull on the incomingFriendRequests field for remove selected objectId and then you need to perform another update query on friends for add selected objectId. also, you can use $addToSet to preventing duplication id. if you use $push for add in that case duplicate objectId also store.
Query :-
1) Remove :- db.getCollection('testdata').update({id:ObjectId('5cc3fa66a04275096417f9ca')},{"$pull":{"incomingFriendRequests":"5cc3fa66a04275096417f9da"}}});
2) add :-
db.getCollection('testdata').update({id:ObjectId('5cc3fa66a04275096417f9ca')},{"$addToSet":{"friends":"5cc3fa66a04275096417f9da"}}); // also you can use $push
Moving values from one field to another would definitely need n + 1 calls to do the transformation. This can be achieved using
find({}).forEach(function(doc) {
// your doc update
doc.save();
});
Or you can even perform a bulkwrite.
In case if your goal is to delete the column incomingFriendRequests, you can probably rename the column to friends instead copying all the data.
update({}, { $rename: {incomingFriendRequests: friends }});
I´m using MongoDB and mongoose for a project that needs to track data creation and changes. The requirements are that I need to keep track of records creation and changes including the date/time and the application user (not the OS user) who did it.
I´ve seen the mongoose timestamps option that would solve my date/time issue, but is there a way to extend it to include extra properties, where I´m gonna be adding the application username ?
If not, is there a single place where I can write a function that will be called on every creation/update so that I can include/modify these fields ?
Today I´m insering these properties on every model like below, but I would like to move all of them to a single place.
var companySchema = mongoose.Schema({
name: {
type: String,
index: true
},
phone: {
type: String
},
deleted: {
type: Boolean
},
createdAt: {
type: Date
},
createdBy: {
type: String
},
updatedAt: {
type: Date
},
updatedBy: {
type: String
}
});
How would be the best approach for it ?
I would approach it by creating two models, one for each Data created, one for each Data Changes.
Data created which will have 6 fields one is createdBy, createdAt, and one will be a field with an array of reference id of Data Changes, deletedBy, deletedAt, deletedFlag.
Data Changes will have fields dataID which will have reference id of data created, updatedBy and updatedAt.
This way it will be easy to keep track of when it was created when it was changes and when it was deleted.
PS: You can remove either of Array in Data created model or dataID ref id in Data Change mode, it was just me being extra cautious while binding.
(EDITED to clarify that I want to delete/drop an attribute from the database when it is deleted from an object)
I have a small Sails application with a schema-less model that allows attributes to be added and saved to the database (currently just the sails-disk file system adaptor for testing purposes).
The problem I am having is that I can't find a way to permanently delete attributes from the database.
When I delete an attribute on an object which is a model instance I also want the attribute dropped from the database. This will be useful when I move to an object database like MongoDB and have objects with dynamically created attributes.
Deleting an attribute using delete object[attributeName] and then saving with the instance method object.save() does not work, the deleted attributes still remain.
For example if I have this object:
{
"name": "Chair",
"colour": "white"
}
Let's say I want to remove the colour attribute to replace it with a material attribute like this:
{
"name": "Chair",
"material": "pine"
}
After updating the object in the database the new material attribute is added, but the deleted colour attribute is not removed.
So the end result in the database will be this:
{
"name": "Chair",
"colour": "white",
"material": "pine"
}
So this is not the outcome I am after.
Is there a way to permanently delete/drop attributes from an object in the database using Sails/Waterline?
I am sure it is too late for this but I had the same issue. What I did was just create a new object and delete the old one. If you want to do this programatically, just compare the key of the current object and the old one. The problem with this is that you must also update all related models (and collections) with the new id.
You can't by default "unset" an attribute because structured SQL databases do not work that way. You can set the attribute to NULL is the most you can do with straight SailsJS. In a structured DB like MySql, MSSQL, Oracle, PGSQL when you do not supply an attribute the DB will insert a default value (NULL or other prescribed value by the schema definition) or throw an error at you.
For NoSQL DB like Mongo they do have an "unset" option which Sails does not support out of the box. In Sails you would have to do a native query using sails.model["name"].getDatastore().manager then run the native Mongo update query using $unset to remove the attribute.
const db = sails.model["products"].getDatastore().manager;
await db.collection("products").update(
{ sku: "unknown" },
{ $unset: { quantity: "", instock: "" } });
** updateMany can also be used the same way for multiple records at the same time.
ref: https://docs.mongodb.com/manual/reference/operator/update/unset/
Otherwise document replacement (cringe) is the only other alternative as stated before.
I'm trying to make a real-time vote application using SailsJS, and am currently having troubles with MongoDB. I am completely new to this, and have been just using SailsJS mimic easy calls to access MongoDB.
module.exports = {
attributes: {
selectOptions:{
type: 'Object'
},
question:{
type:'string',
required: true
},
password:{
type:'string',
required: true
}
}
};
The above code is for the model that I have, and I am the selectOptions should have an array of objects, like [{id: 1,result: 0},{id:2,result 0},...] and would like to know how to do this, as I cannot seem to find any documentation about the array of objects. Only thing I found was something about collection, or making another model and link that to the original model, but when i tried it, sails gave me some foreign key error that I have never faced before. I really really appreciate your time, and look forward for the response.
P.S - I tried making the array into either JSON or Object or nothing(Like not put any type under selectOptions) and made change to the model as well to see if it works, but both JSON and Object didn't work, but selectOptions did. However, I think it was returning a string, as it the length was longer than what the array was supposed to be.
I am new to sails.js. I want to select all record from a table. How to use .find() .
Specially how waterline will know from which table i want data ? Because we are not mentioning any table name in model. I know there is .query(). But is this possible within waterline basic create / update / find / delete method ?
Another question how to use prefix for table name in sails.js ? Like i want to use sails_product as table name.
I am new to sails.js. I want to select all record from a table. How to use .find() .
If your model name is, for example, Book, you'd select all Book records with
Book.find()
.exec(function(err, books) {
if (err) return res.serverError();
console.log(books); // 'books' is an array of the found records
})
Specially how waterline will know from which table i want data ? Because we are not mentioning any table name in model. I know there is .query(). But is this possible within waterline basic create / update / find / delete method ?
Yes, it's possible. You don't have to deal with table names and such at all with waterline, all you need is your model name. Create, update, delete all work the same way as the find example above - so ModelName.actionName().
Another question how to use prefix for table name in sails.js ? Like i want to use sails_product as table name.
By default, waterline uses the model name lowercased as the corresponding table name. You can, however, overwrite this in your model settings. For example, if you have your model defined in a file called Book.js, its contents would look like this:
module.exports = {
attributes: {
name: {
type: 'String',
required: true
},
price: {
type: 'float'
}
},
tableName: 'custom_book_table'
}
This way the actual table created in the database will be called custom_book_table, while you'll still refer to your model in find queries etc. as Book.
Here's links to both Waterline and Sails docs to get you going. In model/query related issues, I'd definitely search from Waterline docs first.