MongoDB data modeling help needed (Opinions on specific data modeling) - node.js

I am creating a web application (Email Marketing Platform) and I am using MERN stack i.e. MongoDB as database, I am not very familiar with NoSQL.
In my application I need to store many contacts for every user (Each user will have their own contacts). I do have a users collection for storing user's information but I am confused on how to store their contacts, I have 3 options I would like to know advantage and disadvantage of these methods if any:
Storing in the user document (Using an array but having many contacts let say 50000 will create an issue for a single document, It's what I think.)
// User document
{
_id: ObjectId("6257e229244ccce02d96169e"),
name: 'Areeb Ahmad',
username: 'areeb',
password: '123',
contacts: [
{
_id: ObjectId("625b271536a6a83858b91d26"),
name: 'contact1',
email: 'contact1#gmail.com',
address: 'Some XYZ Street',
tags: ['tag1', 'tag2', 'tag3'],
source: 'website form',
age: 18,
gender: 'male',
isSubscribed: true,
dateAdded: 'some date',
dateModified: 'Some Date',
}, {
_id: ObjectId("625b271536a6a15788b91d26"),
name: 'contact2',
email: 'contact2#gmail.com',
address: 'Some XYZ Street',
tags: ['tag1', 'tag2', 'tag3'],
source: 'website form',
age: 28,
gender: 'female',
isSubscribed: false,
dateAdded: 'some date',
dateModified: 'Some Date',
}
]
__v: 0
}
Storing all the contacts in separate collection but store their id's in the user document but I think having large amount of contacts can cause issues.
// User Document
{
_id: ObjectId("6257e229244ccce02d96169e"),
name: 'Areeb Ahmad',
username: 'areeb',
password: '123',
contacts: [
ObjectId("625b271536a6a83858b91d26"),
ObjectId("178b271534a6a83858b91d26"),
ObjectId("741b271536a6a83858b91d26"),
ObjectId("854b271536a6a83858b91d26")
]
__v: 0
}
Storing all the contacts in separate collection but store their owner's (users') id in them.
// Contacts Document
{
_id: ObjectId("625b271536a6a15788b91d26"),
user_id : ObjectId("62530cdbf7b28d7da57634af"),
name: 'contact2',
email: 'contact2#gmail.com',
address: 'Some XYZ Street',
tags: ['tag1', 'tag2', 'tag3'],
source: 'website form',
age: 28,
gender: 'female',
isSubscribed: false,
dateAdded: 'some date',
dateModified: 'Some Date',
}
Please let me know which one should I go with, and why, Any other suggestions or ways are more than welcome.

Related

TypeORM return items ordered by most matches

Is there a simple way to return filtered items based on most matches.
For example if I have the following items in my DB:
Customer 1:
{
name: 'Customer 1',
street: 'Examplestreet 1',
}
Customer 2:
{
name: 'Name',
street: 'Examplestreet 2',
}
and then I'd search for name: "Name" and street: "Example".
I'd like to get the following results, because the first customer has two matches one in name and one in street and the second customer only has a match in street:
[
{
name: 'Name',
street: 'Examplestreet 2',
},
{
name: 'Customer 1',
street: 'Examplestreet 1',
}
]
Is there an easy way to do this using NestJS TypeORM Querybuilder?
Thanks

Mongoose Aggregate - Group by field from array

For one of my project, I am working on MongoDB database and Mongoose as ODM in nestjs project.
One of my collection is looks like this data:
[
{
_id: '56cb91bdc3464f14678934ca',
organization: 'New Circle Ltd',
rooms: [
{
name: 'Alex',
workId: 'abc',
},
{
name: 'John',
workId: 'cde',
},
{
name: 'John',
workId: 'abc',
},
{
name: 'Alex',
workId: 'cdlw',
},
{
name: 'Alex',
workId: 'rps',
},
],
},
];
The requirement is to get one data by id and the data should be like the data provided bellow.
{
_id: '56cb91bdc3464f14678934ca',
organization: 'New Circle Ltd',
rooms: [
{
name: 'Alex',
workIds: ['abc', 'cdlw', 'rps'],
},
{
name: 'John',
workIds: ['cde', 'abc'],
},
],
},
Please suggest me how can I get this data

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

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.

Resources