Sails.js Same Model many to many association - node.js
Sails.js .10 rc8
I've completely run out of ideas for this
I have a model called User and I want to associate it in a collection to other users like a friends list. Like a many-to-many association
//User.js
friends: {
collection: 'user',
via: 'friends'
}
but when I run
.populate('friends')
it doesn't populate anything. Any ideas?
I find that the best way to implement this is actually adding a reference to the id.
Check this User model:
module.exports = {
attributes: {
name: {
type: 'string',
required: true,
minLength: 2
},
email: {
type: 'email',
required: true,
unique: true
},
friends: {
collection: 'user',
via: 'id'
}
}
};
Now, if you run sails console you can test the following commands:
User.create({name:'test',email:'test#test.com'}).exec(console.log);
It returns:
{ name: 'test',
email: 'test#test.com',
createdAt: '2016-12-01T22:06:19.723Z',
updatedAt: '2016-12-01T22:06:19.723Z',
id: 1 }
You created your first user. Lets create some other ones:
User.create({name:'test2',email:'test2#test.com'}).exec(console.log);
Resulting in:
{ name: 'test2',
email: 'test2#test.com',
createdAt: '2016-12-01T22:06:40.808Z',
updatedAt: '2016-12-01T22:06:40.808Z',
id: 2 }
Let's see what we have so far:
User.find().populate('friends').exec(console.log);
[ { friends: [],
name: 'test',
email: 'test#test.com',
createdAt: '2016-12-01T22:06:19.723Z',
updatedAt: '2016-12-01T22:06:19.723Z',
id: 1 },
{ friends: [],
name: 'test2',
email: 'test2#test.com',
createdAt: '2016-12-01T22:06:40.808Z',
updatedAt: '2016-12-01T22:06:40.808Z',
id: 2 } ]
Now, let's create a user with a friend, using the reference to the first user. Notice that I just pass a single id, not an array:
User.create({name:'test3',email:'test3#test.com', friends:1}).exec(console.log);
Now, the result is this one. Notice that "friends" does not appear. This is by design.
{ name: 'test3',
email: 'test3#test.com',
createdAt: '2016-12-01T22:07:34.988Z',
updatedAt: '2016-12-01T22:07:34.994Z',
id: 3 }
Let's do a find with populate to see the current status:
User.find().populate('friends').exec(console.log);
Now we see that the third user has friends. The others have an empty array.
[ { friends: [],
name: 'test',
email: 'test#test.com',
createdAt: '2016-12-01T22:06:19.723Z',
updatedAt: '2016-12-01T22:06:19.723Z',
id: 1 },
{ friends: [],
name: 'test2',
email: 'test2#test.com',
createdAt: '2016-12-01T22:06:40.808Z',
updatedAt: '2016-12-01T22:06:40.808Z',
id: 2 },
{ friends:
[ { name: 'test',
email: 'test#test.com',
createdAt: '2016-12-01T22:06:19.723Z',
updatedAt: '2016-12-01T22:06:19.723Z',
id: 1 } ],
name: 'test3',
email: 'test3#test.com',
createdAt: '2016-12-01T22:07:34.988Z',
updatedAt: '2016-12-01T22:07:34.994Z',
id: 3 } ]
Let's create a fourth one, this time with two friends:
User.create({name:'test4',email:'test4#test.com', friends:[1,2]}).exec(console.log);
Resulting in (again, no friends property):
{ name: 'test4',
email: 'test4#test.com',
createdAt: '2016-12-01T22:07:50.539Z',
updatedAt: '2016-12-01T22:07:50.542Z',
id: 4 }
This time, we passed an array of ids to friends. Let's see the current status:
User.find().populate('friends').exec(console.log);
[ { friends: [],
name: 'test',
email: 'test#test.com',
createdAt: '2016-12-01T22:06:19.723Z',
updatedAt: '2016-12-01T22:06:19.723Z',
id: 1 },
{ friends: [],
name: 'test2',
email: 'test2#test.com',
createdAt: '2016-12-01T22:06:40.808Z',
updatedAt: '2016-12-01T22:06:40.808Z',
id: 2 },
{ friends:
[ { name: 'test',
email: 'test#test.com',
createdAt: '2016-12-01T22:06:19.723Z',
updatedAt: '2016-12-01T22:06:19.723Z',
id: 1 } ],
name: 'test3',
email: 'test3#test.com',
createdAt: '2016-12-01T22:07:34.988Z',
updatedAt: '2016-12-01T22:07:34.994Z',
id: 3 },
{ friends:
[ { name: 'test',
email: 'test#test.com',
createdAt: '2016-12-01T22:06:19.723Z',
updatedAt: '2016-12-01T22:06:19.723Z',
id: 1 },
{ name: 'test2',
email: 'test2#test.com',
createdAt: '2016-12-01T22:06:40.808Z',
updatedAt: '2016-12-01T22:06:40.808Z',
id: 2 } ],
name: 'test4',
email: 'test4#test.com',
createdAt: '2016-12-01T22:07:50.539Z',
updatedAt: '2016-12-01T22:07:50.542Z',
id: 4 } ]
Now, how do you add a friend to an existing user? It's somehow odd: you have to first find the user, then use the add function on the resulting model, and then, save it. In my day to day code, I have a helper function that does just that. So, here is the example:
User.findOne(1).populate('friends').exec(function(err,u){ u.friends.add(3);u.save(function(err){ if(err) console.error(err);});});
Now in the console we see no results.
Let's check the User content now:
User.find().populate('friends').exec(console.log);
[ { friends:
[ { name: 'test3',
email: 'test3#test.com',
createdAt: '2016-12-01T22:07:34.988Z',
updatedAt: '2016-12-01T22:07:34.994Z',
id: 3 } ],
name: 'test',
email: 'test#test.com',
createdAt: '2016-12-01T22:06:19.723Z',
updatedAt: '2016-12-01T22:09:41.410Z',
id: 1 },
{ friends: [],
name: 'test2',
email: 'test2#test.com',
createdAt: '2016-12-01T22:06:40.808Z',
updatedAt: '2016-12-01T22:06:40.808Z',
id: 2 },
{ friends:
[ { name: 'test',
email: 'test#test.com',
createdAt: '2016-12-01T22:06:19.723Z',
updatedAt: '2016-12-01T22:09:41.410Z',
id: 1 } ],
name: 'test3',
email: 'test3#test.com',
createdAt: '2016-12-01T22:07:34.988Z',
updatedAt: '2016-12-01T22:07:34.994Z',
id: 3 },
{ friends:
[ { name: 'test',
email: 'test#test.com',
createdAt: '2016-12-01T22:06:19.723Z',
updatedAt: '2016-12-01T22:09:41.410Z',
id: 1 },
{ name: 'test2',
email: 'test2#test.com',
createdAt: '2016-12-01T22:06:40.808Z',
updatedAt: '2016-12-01T22:06:40.808Z',
id: 2 } ],
name: 'test4',
email: 'test4#test.com',
createdAt: '2016-12-01T22:07:50.539Z',
updatedAt: '2016-12-01T22:07:50.542Z',
id: 4 } ]
With this method, you can even add the same user to the friends collection!
User.findOne(1).populate('friends').exec(function(err,u){ u.friends.add(1);u.save(function(err){ if(err) console.error(err);});});
Have fun!
Your models should look like this...
//User.js
friends: {
collection: 'friend',
via: 'user'
}
//Friend.js
user: {
model: 'user'
via: 'friends'
}
Also sails 10 rc8 is old. You should be on sails 10.5
You should use .populate('friends') instead of .populate(friends)
As it turns out, when you have a many to many association in waterline you have to declare one of the models as dominant. Since they are the same model, neither is dominated. While a join table is created, there is no way to populate it.
Related
How to pass the entire data in databese to an array in node js (using mongoose)
How to pass the entire data in databese to an array in node js (using mongoose)
Model.find({}) should be your answer. It is an asynchronous function so use async/await or a callback. e.g await User.find({}) OUTPUT: [ { age: 0, _id: 62ae10acd37b5a38cfc089b7, name: 'john mclain', email: 'example#gmail.com', password: '', tokens: [ [Object] ], createdAt: 2022-06-18T17:51:40.895Z, updatedAt: 2022-06-18T17:51:40.936Z, __v: 1 }, { age: 1, _id: 62ae10acd37b5a38cfc089b7, name: 'john mclain2', email: 'example#gmail.com', password: '', tokens: [ [Object] ], createdAt: 2022-06-18T17:51:40.895Z, updatedAt: 2022-06-18T17:51:40.936Z, __v: 2 } ]
Accessing JSON objects in this format
const login = await Signupdetails.find(req.body); login = [ { PersonalInformation: { firstName: 'aravind', lastName: 'john', phoneNumber: 9736363777, DOB: 1999-07-08T18:30:00.000Z }, Address: { street: 'pillai', city: 'Chennai', pincode: 89997, state: 'kerala', country: 'India' }, password: 'social', _id: 607804f65c166c32144ae227, email: 'hari#gmail.com', userName: 'hari', __v: 0 } ] If I try using login.userName ,its showing undefined . This is a part of my Get API request . I used node.js and mongodb
You have a list, if you want login to be an Object, remove '[' characters: login = { PersonalInformation: { firstName: 'aravind', lastName: 'john', phoneNumber: 9736363777, DOB: 1999-07-08T18:30:00.000Z }, Address: { street: 'pillai', city: 'Chennai', pincode: 89997, state: 'kerala', country: 'India' }, password: 'social', _id: 607804f65c166c32144ae227, email: 'hari#gmail.com', userName: 'hari', __v: 0 } On the other hand, if you want login to be a list, you have to access: login[0].userName
How to insert array in MongoDB? Node Js
I'm working on Node js server and use the mongoDB with driver mongoose. So, how can I insert an array in database. Here is my Schema: const SubjectsSchema = new Schema( { id: { type: String, required: true, }, subjects: [ { id: { type: Number, required: true }, subject: { type: String, required: true }, }, ], }, { versionKey: false } ); And here how I add new element: let subjects = new Subjects({ id: req.params.class, subjects: { id: 0, subject: "Maths"}, subjects: {id: 1, subject: "IT"}, subjects: {id: 2, subject: "Physics"}, }); subjects.save(); But in db created only last element. So how can create a correct array?
You are supposed to pass it as an array, like your model definition let subjects = new Subjects({ id: req.params.class, subjects: [{ id: 0, subject: "Maths"}, {id: 1, subject: "IT"}, {id: 2, subject: "Physics"} ] }); subjects.save();
Find In array TypeOrm
Let's see if you can help me, because I've been like this for a few hours and I can't. I'm doing some queries with Typeorm, and this is the situation: I have an array of Ids: ["array1, array1, array3"]. that is, in the array an id is repeated 2 times. The thing is that if I make a query such that: const found = await this.find ({ where: {id: In (Ids)}, }) In found what I have is: [ Catalog { id: 'array1', image: 'https://image.jpg', name: 'Article name', description: 'Description', price: 809, createdAt: 2020-12-04T17:34:16.869Z, updatedAt: 2020-12-04T17:34:16.869Z }, Catalog { id: 'array3', image: 'https://image.jpg', name: 'Article name', description: 'Description', price: 809, createdAt: 2020-12-04T17:34:16.869Z, updatedAt: 2020-12-04T17:34:16.869Z } ] And that I need is: [ Catalog { id: 'array1', image: 'https://image.jpg', name: 'Article name', description: 'Description', price: 809, createdAt: 2020-12-04T17:34:16.869Z, updatedAt: 2020-12-04T17:34:16.869Z }, Catalog { id: 'array1', image: 'https://image.jpg', name: 'Article name', description: 'Description', price: 809, createdAt: 2020-12-04T17:34:16.869Z, updatedAt: 2020-12-04T17:34:16.869Z }, Catalog { id: 'array3', image: 'https://image.jpg', name: 'Article name', description: 'Description', price: 809, createdAt: 2020-12-04T17:34:16.869Z, updatedAt: 2020-12-04T17:34:16.869Z } ] Another option would be to do next a method that receiving the parameters of the ID array and the object, iterate to obtain the array of objects that I need ... but I have not found the key either. Thanks for you help
Finally, i do this: const order: CatalogDto[] = [] for (let i = 0; i < Ids.length; i++) { const found: CatalogDto = uniqueProduct.find(product=> product.id == Ids[i]) order.push(found) } where uniqueProduct is : [ Catalog { id: 'array1', image: 'https://image.jpg', name: 'Article name', description: 'Description', price: 809, createdAt: 2020-12-04T17:34:16.869Z, updatedAt: 2020-12-04T17:34:16.869Z }, Catalog { id: 'array3', image: 'https://image.jpg', name: 'Article name', description: 'Description', price: 809, createdAt: 2020-12-04T17:34:16.869Z, updatedAt: 2020-12-04T17:34:16.869Z } ] and in order I have: [ Catalog { id: 'array1', image: 'https://image.jpg', name: 'Article name', description: 'Description', price: 809, createdAt: 2020-12-04T17:34:16.869Z, updatedAt: 2020-12-04T17:34:16.869Z }, Catalog { id: 'array1', image: 'https://image.jpg', name: 'Article name', description: 'Description', price: 809, createdAt: 2020-12-04T17:34:16.869Z, updatedAt: 2020-12-04T17:34:16.869Z }, Catalog { id: 'array3', image: 'https://image.jpg', name: 'Article name', description: 'Description', price: 809, createdAt: 2020-12-04T17:34:16.869Z, updatedAt: 2020-12-04T17:34:16.869Z } ]
Mongodb update push Array of Objects
I am unable to solve this issue (and looking to avoid loop update one by one), please hep me out here. I have a fambio document (which has its own FamilyModel) which gets created after user gives his below information: { name: 'john', lname: 'doe', } Now, after above information gets saved, user provides more information about the family after some processing in backend: let familyArr = [ { _id: 1234, name: 'Jenny', lname: 'doe', relation: 'mother' }, { _id: 2345, name: 'Jawn', lname: 'doe', relation: 'father' }, { _id: 3456, name: 'Jane', lname: 'doe', relation: 'sister' }, { _id: 4567, name: 'Daisy', lname: 'wick', relation: 'pupper' } ] Altogether, FamilyModel schema looks like: const FamilyModel = mongoose.Schema({ name: {type: String, required: true}, lname: {type: String, required: true}, family: [relationshipSchema] }, { timestamp: true }); const relationshipSchema = mongoose.Schema({ name: {type: String, required: true}, lname: {type: String, required: true}, relation: {type: String, required: true} }, { required: false, timestamp: true }); Now, John has an array of objects of family (filed type Array) and trying to insert that Array of Object like this: What I tried multiple options: db.fambio.updateOne({_id: 1111}, { $set: { family: familyArr }}) db.fambio.findOneAndUpdate({_id: 1111}, { $push: { family: familyArr }}); db.fambio.update({_id: 1111}, $addToSet: { 'family': familyArr}}); Nothing is working with respect to insert the constructed Object directly to the field. When I insert one at a time, it gets updated. How am I supposed to write the query to update/append an Array of Objects in to a field of Array Type having its own Schema maintained.
Okay, I've solved it. How I solved it: Initially, I saved the document and did some processing on the info as per my requirements post which I wanted to insert Array of Elements in to an Array key field where I was running in to the issue of nothing getting inserted. What I was missing was $each and this is how I did it: db.getCollection('fambio').update({ _id: johnsuserid }, { $push: { 'family': { $each:[ { _id: 1234, name: 'Jenny', lname: 'doe', relation: 'mother' }, { _id: 2345, name: 'Jawn', lname: 'doe', relation: 'father' }, { _id: 3456, name: 'Jane', lname: 'doe', relation: 'sister' }, { _id: 4567, name: 'Daisy', lname: 'wick', relation: 'pupper' } ] } } }); Thank you everyone!! Hope this helps someone who may face this problem in future.