Mongoose mongodb - get all the data from the collections - node.js

I'm using MongoDB with Mongoose,
I want to create an list of countries, each country has a name and a list of cities, and each city has a name and a list of hostels.
the users can add new hostels and rate the existing hostels.
my JSON is supposed to look something like this:
{[
countryName: "Argentina",
cities: [{
cityName: "Buenos Aires",
hostels: [{
hostelName: "hostel A",
hostelLocation: "Florida Street 180",
hostelPhone: "+954454646"
},{
hostelName: "hostel B",
hostelLocation: "28 Mayo Street 180",
hostelPhone: "+959898944"
}]
},{
cityName: "Bariloche",
hostels: [{
hostelName: "hostel C",
hostelLocation: "...",
hostelPhone: "..."
},{
hostelName: "hostel D",
hostelLocation: "...",
hostelPhone: "..."
}]
}]
],
[
countryName: "Brazil",
cities: [{
cityName: "Rio De Janero",
hostels: [{
hostelName: "hostel A",
hostelLocation: "...",
hostelPhone: "..."
},{
hostelName: "hostel B",
hostelLocation: "...",
hostelPhone: "..."
}]
},{
cityName: "Salvador",
hostels: [{
hostelName: "hostel C",
hostelLocation: "...",
hostelPhone: "..."
},{
hostelName: "hostel D",
hostelLocation: "...",
hostelPhone: "..."
}]
}]
]
}
How do I implement this structure in Mongo?

Have you tried creating models?http://docs.mongodb.org/manual/core/data-modeling-introduction/
Consider using separated cities and having redundant country parameters for a single model method. Also consider using multiple models for not redundant storage.
city name: String,
country: String,
hostels: {hostel info / model reference}
If you want an example app try the one I used.
https://scotch.io/tutorials/using-mongoosejs-in-node-js-and-mongodb-applications

Related

How to update my nested array of another nested array in object in mongodb

My problem is somehow related to this problem LINK. However this is my problem..
{
"_id": ObjectId("4d2d8deff4e6c1d71fc29a07"),
"comments": [{
"name": "Len",
"_id": ObjectId("6241108375ed952ceb0187e3"),
"data": [{
"name":"Len",
"confirmation_likes":"false",
"_id":ObjectId("6241102d75ed952ceb0187dd")
},{
"name":"Lilipad",
"confirmation_likes":"false",
"_id":ObjectId("6241102d75ed952ceb0187da")
}]
} {
"name": "Lilipad",
"_id": ObjectId("6241108375ed952ceb0187e5"),
"data": [{
"name":"Len",
"confirmation_likes":"false",
"_id":ObjectId("6241102d75ed952ceb0187dd")
},{
"name":"Lilipad",
"confirmation_likes":"false",
"_id":ObjectId("6241102d75ed952ceb0187da")
}]
} {
"name": "Leni Robredo",
"_id": ObjectId("6241108375ed952ceb0187e9"),
"data": [{
"name":"Len",
"confirmation_likes":"false",
"_id":ObjectId("6241102d75ed952ceb0187dd")
},{
"name":"Lilipad",
"confirmation_likes":"false",
"_id":ObjectId("6241102d75ed952ceb0187da")
}]
}
...
]
}
Now, what I want to happen here is when you get the _id of the comments such as ObjectId("6241108375ed952ceb0187e3"),ObjectId("6241108375ed952ceb0187e5"),ObjectId("6241108375ed952ceb0187e9"). I want update a new set of data for each of them, but I am so confused how I am gonna do it with the operator. This is how my inputs gonna work and the output.
parent_id = ObjectId("4d2d8deff4e6c1d71fc29a07")
sub_id = ObjectId("6241108375ed952ceb0187e5")
new_data = [{
"name":"Len",
"confirmation_likes":"false",
"_id":ObjectId("6241102d75ed952ceb0187dd")
},{
"name":"Lilipad",
"confirmation_likes":"false",
"_id":ObjectId("6241102d75ed952ceb0187da")
},{
"name":"Len",
"confirmation_likes":"false",
"_id":ObjectId("6241102d75ed952ceb012131")
}]
Output
{
"_id": ObjectId("4d2d8deff4e6c1d71fc29a07"),
"comments": [{
"name": "Len",
"_id": ObjectId("6241108375ed952ceb0187e3"),
"data": [{
"name":"Len",
"confirmation_likes":"false",
"_id":ObjectId("6241102d75ed952ceb0187dd")
},{
"name":"Lilipad",
"confirmation_likes":"false",
"_id":ObjectId("6241102d75ed952ceb0187da")
}]
} {
"name": "Lilipad",
"_id": ObjectId("6241108375ed952ceb0187e5"),
"new_data": [{
"name":"Len",
"confirmation_likes":"false",
"_id":ObjectId("6241102d75ed952ceb0187dd")
},{
"name":"Lilipad",
"confirmation_likes":"false",
"_id":ObjectId("6241102d75ed952ceb0187da")
},{
"name":"Len",
"confirmation_likes":"false",
"_id":ObjectId("6241102d75ed952ceb012131")
}]
} {
"name": "Leni Robredo",
"_id": ObjectId("6241108375ed952ceb0187e9"),
"data": [{
"name":"Len",
"confirmation_likes":"false",
"_id":ObjectId("6241102d75ed952ceb0187dd")
},{
"name":"Lilipad",
"confirmation_likes":"false",
"_id":ObjectId("6241102d75ed952ceb0187da")
}]
}
...
]
}
As you see I use sub_id to get the id of the item of an array that I want to update its data..because I can use the same name but not the id so that's why I used _id of array items of comments.
Now what If I want to my pass new all data in all id of comment array.. I already prepare a loop for that let say something likes this.
list_comment_id = [ObjectId("6241108375ed952ceb0187e3"),
ObjectId("6241108375ed952ceb0187e5"),ObjectId("6241108375ed952ceb0187e9")]
parent_id = ObjectId("4d2d8deff4e6c1d71fc29a07")
new_data = [{
"name":"Len",
"confirmation_likes":"false",
"_id":ObjectId("6241102d75ed952ceb0187dd")
},{
"name":"Lilipad",
"confirmation_likes":"false",
"_id":ObjectId("6241102d75ed952ceb0187da")
},{
"name":"Len",
"confirmation_likes":"false",
"_id":ObjectId("6241102d75ed952ceb012131")
}]
And so that i will pass up all the data that my list_comment_id wants..
I already tried something like this in my code
router.route('/append/:id').put((req,res) => {
const { _id, sub_id, data} = req.body
const main_id = req.params.id
// Sub_id for comments _id items
COMMENT.updateOne(
{
_id:main_id,
"comments._id" : sub_id
},
{
$set:{
data:data
}
}
).then((comments) => res.json("Likes List People Updated") )
.catch(err => console.log(err))
})
Anyone can help me please thank you?? I'll be gladly thankful.
Maybe something like this:
db.collection.update({
_id: ObjectId("4d2d8deff4e6c1d71fc29a07")
},
{
$set: {
"comments.$[x]": {
"name": "Lilipad",
"_id": ObjectId("6241108375ed952ceb0187e5"),
"new_data": [
{
"name": "Len",
"confirmation_likes": "false",
"_id": ObjectId("6241102d75ed952ceb0187dd")
},
{
"name": "Lilipad",
"confirmation_likes": "false",
"_id": ObjectId("6241102d75ed952ceb0187da")
},
{
"name": "Len",
"confirmation_likes": "false",
"_id": ObjectId("6241102d75ed952ceb012131")
}
]
}
}
},
{
arrayFilters: [
{
"x._id": ObjectId("6241108375ed952ceb0187e5")
}
]
})
Explained:
Create arrayFilters x to identify which element need to be updated and update with the necessary values.
playground

MongoDb Shell syntaxError after property id

db.students.insertOne({
_id: 1001,
Firstname: "John",
Lastname: "smith",
Address: {
Streetaddress: "123 Monash Drive",
Suburb: "Clayton",
State: "VIC",
Postcode: 3168,
},
Gender: "Male",
Course: "BITS",
Year: 2019,
"Off-Campus": "false",
Email: ["jsmith#gmail.com", "jsmith#yahoo.com"],
});
After type these, i got the error of uncaught exception: SyntaxError: missing : after property id :.
Idk why this happen.
The document which you are trying to insert isn't a valid JSON, try with the following -
db.students.insertOne({
"_id": 1001,
"Firstname": "John",
"Lastname": "smith",
"Address": {
"Streetaddress": "123 Monash Drive",
"Suburb": "Clayton",
"State": "VIC",
"Postcode": 3168
},
"Gender": "Male",
"Course": "BITS",
"Year": 2019,
"Off-Campus": "false",
"Email": [
"jsmith#gmail.com",
"jsmith#yahoo.com"
]
});

How should I fetch data from another collection and join with the result

I have an endpoint which gives me a list of all Profiles available, now I have a Post Schema & Profile Schema, I want to add a list of posts that specific users have made to my result
Code present in endpoint
const profiles = await Profile.find()
.populate('user', [
'name',
'avatar'
])
Profile Schema
const ProfileSchema = new mongoose.Schema({
user: {
type: mongoose.Schema.Types.ObjectId,
ref: 'user'
},
post: [],
........
Post Schema
const PostSchema = new Schema({
user: {
type: Schema.Types.ObjectId,
ref: 'user'
},
text: {
type: String,
required: true
},
........
Response
[
{
"social": {
"youtube": "https://youtube.com/.",
"twitter": "https://twitter.com/.",
"facebook": "https://fb.com/."
},
"post": [], //This should populate
"skills": [
"HTML",
"CSS",
"PHP",
"Ruby"
],
"_id": "5ced6cb9e3f7485ee2cb0445",
"user": {
"_id": "5ced02551b60fe20afc72a32",
"name": "John abc",
"avatar": "//www.gravatar.com/avatar/1f9d9a9efc2f523b2f09629444632b5c?s=200&r=pg&d=mm"
},
"status": "Developer",
"experience": [
{
"current": true,
"_id": "5ceebb30bb0c667b85a94f97",
"from": "2010-08-09T18:30:00.000Z",
"description": "lorem ipasum"
}
],
"date": "2019-05-28T17:15:37.755Z",
"__v": 30,
"bio": "I am dev",
"education": [
{
"current": false,
"_id": "5cf0c1dc6b8dc33cd68be560",
"degree": "BE",
"from": "2005-07-09T18:30:00.000Z",
"to": "2010-03-03T18:30:00.000Z",
"description": "Got BE"
}
]
}
]
Expected output
[
{
"social": {
"youtube": "https://youtube.com/.",
"twitter": "https://twitter.com/.",
"facebook": "https://fb.com/."
},
"post": [
{_id:98as98djakjbkasd,
text:"This is post by xyz user"
},
{_id:234oijaoijd,
text:"This is another post by xyz user"
}
]
"skills": [
"HTML",
"CSS",
"PHP",
"Ruby"
],
"_id": "5ced6cb9e3f7485ee2cb0445",
"user": {
"_id": "5ced02551b60fe20afc72a32",
"name": "John abc",
"avatar": "//www.gravatar.com/avatar/1f9d9a9efc2f523b2f09629444632b5c?s=200&r=pg&d=mm"
},
.....
I want to populate posts done by the same user, what changes are needed to be done in endpoint code.
I am new to mongoose, upon searching for solutions I found aggregate could be useful but it cannot be used like .find().aggregate([...])
Trying to join in MongoDB would defeat the purpose of using MongoDB. As we first think about our use case then decide database and schema. You could however use DBref and write your own application code.
Another thing you can alter your schema into a single collection and use embedded document
It's always a suggestion of MongoDB that avoid join in our query!

how to filter after populated mongodb [duplicate]

This question already has answers here:
Querying after populate in Mongoose
(6 answers)
Closed 5 years ago.
I need to filter my business document according to a type of service.
var BusinessSchema = Schema({
name: String,
slug: String,
service: [{type: Schema.ObjectId, ref: 'Service'}],
owner: {type: Schema.ObjectId, ref: 'User'}
});
module.exports = mongoose.model('Business', BusinessSchema);
And Schema service is:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var ServiceSchema = Schema({
name: String,
});
module.exports = mongoose.model('Service', ServiceSchema);
Of this array of businesses would only need those that have within its services the "Service A" for example.
"business": [
{
"_id": "594957df4e195d2500324726",
"owner": "59482e80d4df7208503154b8",
"slug": "Almacene2s",
"name": "Almacene2s",
"__v": 0,
"service": [
{
"_id": "594ab160778ae82c44af3a78",
"name": "Service C",
"__v": 0
},
{
"_id": "594ab1be778ae82c44af3a7a",
"name": "Service D",
"__v": 0
}
],
},
{
"_id": "5948483e6bcc1f2788b09145",
"owner": "59482e80d4df7208503154b8",
"slug": "guaranda-2",
"name": "Guaranda Fig",
"service": [
{
"_id": "594ab160778ae82c44af3a78",
"name": "Service A",
"__v": 0
},
{
"_id": "594ab1be778ae82c44af3a7a",
"name": "Service B",
"__v": 0
}
],
}
]
In this case the result I want to get is:
{
"_id": "5948483e6bcc1f2788b09145",
"owner": "59482e80d4df7208503154b8",
"slug": "guaranda-2",
"name": "Guaranda Fig",
"service": [
{
"_id": "594ab160778ae82c44af3a78",
"name": "Service A",
"__v": 0
},
{
"_id": "594ab1be778ae82c44af3a7a",
"name": "Service B",
"__v": 0
}
],
}
It is very important for me to be able to carry out this search, because the system will allow the user to choose as a filter the business that has the desired service.
It's my first project on nodejs + mongodb and I would like your help before continuing on. Thank you very much
Using $lookup, here's what you can achieve:
Service.aggregate([
{
$match: {
"name": "Service A"
}
},
{
$lookup: {
from: "business",
localField: "_id",
foreignField: "service",
as: "businesses"
}
}
], function(err, result) {
console.log(result);
});
In this aggregation pipeline, you first match and find service documents with name "Service A". Then lookup in service array of business documents for matching ones and place them in businesses field. The result will look like this:
{
"_id" : "594af96883ab76db8ecd021b",
"name" : "Service A",
"businesses" : [
{
"_id" : "594af9a683ab76db8ecd0225",
"slug" : "Almacene2s",
"owner" : "59482e80d4df7208503154b8",
"name" : "Almacene2s",
"service" : [
"594af96883ab76db8ecd021b",
"594af96883ab76db8ecd021d"
]
}
]
}

How to link to sub-document using mongoose & node.js

Is it possible using Node.js, Express and Mongoose for MongoDB to have a link to a sub-document.
He is one of my document containing platforms sub-Documents:
// A product description
{
"name": "My product",
"operator": "5288c2bdb0269e1c85000003",
"_id": "528909ff1225faa801000004",
"platforms": [
{
"name": "Platform 1",
"_id": "528909ff1225faa801000007"
},
{
"name": "Platform 2",
"_id": "528909ff1225faa801000006"
},
{
"name": "Platform 3",
"_id": "528909ff1225faa801000005"
}
]
}
I also have a Variable document which have sub-document related to platforms:
// Variable description
{
"name": "My variable",
"values": [
{
"platform": "528909ff1225faa801000007",
"values": "value 1"
},
{
"platform": "528909ff1225faa801000006",
"values": "value 2"
},
{
"platform": "528909ff1225faa801000005",
"values": "value 3"
}
]
}
In Mongoose, is it possible to have a schema reflecting it ?
You can either do this:
ProductSchema = new Schema({
name: {type: String},
operator: {type: Schema.Types.ObjectId},
platforms: [{
name: {type: String},
}],
})
or this:
ProductSchema = new Schema({
name: {type: String},
operator: {type: Schema.Types.ObjectId},
platforms: [PlatformSchema],
})

Resources