How can I make schema Given output using mongoose? - node.js

I have given my output for this how can I make schema.any one give example for this I have added my schema also
My output code:
$scope.countries = [{
"name": "India",
"states": [{
"name": "Maharashtra",
"cities": [{
"name": "Pune"
}, {
"name": "Mumbai"
}, {
"name": "Nagpur"
}, {
"name": "Akola"
}]
}, {
"name": "Madhya Pradesh",
"cities": [{
"name": "Indore"
}, {
"name": "Bhopal"
}, {
"name": "Jabalpur"
}]
}, {
"name": "Rajasthan",
"cities": [{
"name": "Jaipur"
}, {
"name": "Ajmer"
}, {
"name": "Jodhpur"
}]
}]
}, {
"name": "USA",
"states": [{
"name": "Alabama",
"cities": [{
"name": "Montgomery"
}, {
"name": "Birmingham"
}]
}, {
"name": "California",
"cities": [{
"name": "Sacramento"
}, {
"name": "Fremont"
}]
}, {
"name": "Illinois",
"cities": [{
"name": "Springfield"
}, {
"name": "Chicago"
}]
}]
}, {
"name": "Australia",
"states": [{
"name": "NewSouthWales",
"cities": [{
"name": "Sydney"
}]
}, {
"name": "Victoria",
"cities": [{
"name": "Melbourne"
}]
}]
}];
This is my routes:
app.route('/address')
.get(address.list)
.post(address.create);
Controller code:
/**
* Create a address
*/
exports.create = function(req, res) {
var address = new Address(req.body);
address.user = req.user;
address.save(function(err) {
if (err) {
return res.status(400).send({
message: errorHandler.getErrorMessage(err)
});
} else {
res.json(address);
}
});
};
Schema code :
'use strict';
/**
* Module dependencies.
*/
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
var citySchema = {
name: {type:String, required: false}
};
citySchema = 'new Schema('+ citySchema +',{_id:false})';
var stateSchema = {
name: {type:String, required: false},
cities: [citySchema], default:[]
};
stateSchema = 'new Schema('+stateSchema +',{_id:false})';
var countrySchema = {
name: {type:String, required: false},
states: [stateSchema], default:[]
};
// dbObj is mongoose connection object
var collectionObj = dbObj.model('countries', countrySchema);
i have updated my routes and controller schema .how can i change to inser that object pls give some suggestion ?

Please try with following schema :-
var citySchema = {
name: {type:String, required: false}
};
citySchema = 'new Schema('+ citySchema +',{_id:false})';
var stateSchema = {
name: {type:String, required: false},
cities: [citySchema], default:[]
};
stateSchema = 'new Schema('+stateSchema +',{_id:false})';
var countrySchema = {
name: {type:String, required: false},
states: [stateSchema], default:[]
};
// dbObj is mongoose connection object
var collectionObj = dbObj.model('countries', countrySchema);
Now if you want to insert any single country data into db please go through with following procedure-
// Let us assume that we need to insert following data first
var data = {
"name": "India",
"states": [{
"name": "Maharashtra",
"cities": [{
"name": "Pune"
}, {
"name": "Mumbai"
}, {
"name": "Nagpur"
}, {
"name": "Akola"
}]
}, {
"name": "Madhya Pradesh",
"cities": [{
"name": "Indore"
}, {
"name": "Bhopal"
}, {
"name": "Jabalpur"
}]
}, {
"name": "Rajasthan",
"cities": [{
"name": "Jaipur"
}, {
"name": "Ajmer"
}, {
"name": "Jodhpur"
}]
}]
};
// add country
var insertObj = {
"name": "India",
"states": []
}
countryModel.create(insertObj, function (err, job) {
cb(err, job);
});
// add states
var states = [{
"name": "Maharashtra",
"cities": []
}, {
"name": "Madhya Pradesh",
"cities": []
}, {
"name": "Rajasthan",
"cities": []
}];
var stateCond = {"name": "India"};
var stateUpdate = {$push: {states: states}};
var stateOpts = {};
countryModel.findOneAndUpdate(stateCond, stateUpdate, stateOpts, function (err, resp) {
cb(err, resp);
});
// Now if you want to add "Maharastra" Cities
var cities = [{
"name": "Pune"
}, {
"name": "Mumbai"
}, {
"name": "Nagpur"
}, {
"name": "Akola"
}]
var cityCond = {"name": "India", "states.name": "Maharashtra"};
var cityUpdate = {$push: {cities: cities}};
var cityOpts = {};
countryModel.findOneAndUpdate(cityCond, cityUpdate, cityOpts, function (err, resp) {
cb(err, resp);
});
// Now same insertion query need to be run for "Madhya Pradesh" and "Rajasthan"
Thanks

Related

In NodeJS, using simple-odata-server, when insert data in one entity, it inserts data in another entity

I want to use odata in my nodejs project. So i decided to use the package simple-odata-server (https://www.npmjs.com/package/simple-odata-server), that i installed by tapping :
npm i simple-odata-server
My code is inspired by this example (which doesn't work by the way) :
https://codesandbox.io/s/2rzn5?file=/src/index.js:1216-1227
var ODataServer = require("simple-odata-server");
var Adapter = require("simple-odata-server-nedb");
var Datastore = require("nedb");
var http = require("http");
var db = new Datastore({ inMemoryOnly: true });
var model = {
namespace: "jsreport",
entityTypes: {
UserType: {
_id: { type: "Edm.String", key: true },
name: { type: "Edm.String" },
addresses: { type: "Collection(jsreport.AddressType)" }
},
ProductType: {
_id: { type: "Edm.String", key: true },
name: { type: "Edm.String" },
description: { type: "Edm.String" },
}
},
complexTypes: {
AddressType: {
street: { type: "Edm.String" }
}
},
entitySets: {
users: {
entityType: "jsreport.UserType"
},
products: {
entityType: "jsreport.ProductType"
}
}
};
var odataServer = ODataServer("https://localhost:1337/");
odataServer.model(model).adapter(
Adapter(function (coll, cb) {
cb(null, db);
})
);
odataServer.cors("*");
http.createServer(odataServer.handle.bind(odataServer)).listen(1337);
console.log("server running on http://localhost:1337");
Then I add data with postman :
POST http://localhost:1337/products
with body :
[{ "_id" : "1", "name" : "banana"}, {"_id" : "2", "name" : "pineapple"}, {"_id" : "3", "name" : "coconut"},{"_id" : "4", "name" : "orange"}]
If I do : GET http://localhost:1337/products
I got correct result :
{
"#odata.context": "https://localhost:1337//$metadata#products",
"value": [
{
"_id": "1",
"name": "banana"
},
{
"_id": "2",
"name": "pineapple"
},
{
"_id": "3",
"name": "coconut"
},
{
"_id": "4",
"name": "orange"
}
]
}
But if i do GET http://localhost:1337/users
I got a weird result :
{
"#odata.context": "https://localhost:1337//$metadata#users",
"value": [
{
"_id": "1",
"name": "banana"
},
{
"_id": "2",
"name": "pineapple"
},
{
"_id": "3",
"name": "coconut"
},
{
"_id": "4",
"name": "orange"
}
]
}
Updating the entity products, also update entity users.
It means updating an entity update another entity.
I don't know how to solve this.

How to POST with Array inside Array Mongoose Schema

There are my mongoose schemas. I guess its ok. (https://mongoosejs.com/docs/subdocs.html)
const mongoose = require("mongoose");
const itemSchema = mongoose.Schema({
"itemNo": {
"type": "String"
}
});
const mySchema = mongoose.Schema({
"items":[itemSchema],
"title": {
"type": "String"
},
"data": {
"type": "String"
},
"pic": {
"type": "String"
},
"star": {
"type": "Boolean"
},
"category": {
"type": "String"
},
"date": {
"type": "Date"
},
});
module.exports = mongoose.model('dashboards', mySchema);
But im having trouble with post method. How can fix the code?
When i post my json, its returning with empty "items".
router.post("/", (req, res) => {
const post = new Model1({
title: req.body.title,
data: req.body.data,
pic: req.body.pic,
star: req.body.star,
category: req.body.category,
items: [req.body.items]
});
I edited my project like this. My problem is solved.
Here is my schemas.
const mongoose = require("mongoose");
const itemSchema = mongoose.Schema({
"itemNo": {
"type": "String"
},
});
const mySchema = mongoose.Schema({
"title": {
"type": "String"
},
"data": {
"type": "String"
},
"pic": {
"type": "Date"
},
"star": {
"type": "Boolean"
},
"category": {
"type": "String"
},
"items": [itemSchema]
});
module.exports = mongoose.model('dashboards', mySchema);
This is my post request.
router.post("/", (req, res) => {
const post = new Model1({
title: req.body.title,
data: req.body.data,
pic: req.body.pic,
star: req.body.star,
category: req.body.category,
items: req.body.items
});

Update many sub of sub-document array using $set / $push

Following is the Sample Workspace document.I want to update box positions when we drag and drop at front end.
{
"_id": ObjectId("5eaa9b7c87e99ef2430a320b"),
"logo": {
"url": ".../../../assets/logo/dsdsds.png",
"name": "testUpload"
},
"name": "My World",
"sections": [{
"box": [{
"_id": ObjectId("5da87b33502d6c634b3aa7ce"),
"name": "Meran To",
"position": 0
},
{
"_id": ObjectId("5da87b33502d6c7d873aa7d0"),
"name": "Documentation",
"position": 2
},
{
"_id": ObjectId("5da87b33502d6cdbb93aa7cf"),
"name": "File Manager Upload File Drive",
"position": 1
},
{
"_id": ObjectId("5da87b33502d6c276a3aa7cd"),
"name": "File Manager Upload File Drive",
"position": 1
}
],
"id": 1,
"title": "Simplicity",
"description": "Follow your barriers"
},
{
"box": [],
"id": 2,
"title": "xfxdfxcx 34",
"description": "sdsdsd sfsfsd ewrewrewre"
}
]
}
I send the updated positions from front-end to back-end via API, in an array as shown below.
[
{
"id": "5da87b33502d6c634b3aa7ce",
"position": 0
}, {
"id": "5da87b33502d6c7d873aa7d0",
"position": 1
}, {
"id": "5da87b33502d6cdbb93aa7cf",
"position": 2
}, {
"id": "5da87b33502d6c276a3aa7cd",
"position": 3
}]
I am currently updating DB using the below code
for (const el of req.body) {
await this.model.updateOne({
_id: req.params.workspaceId,
sections: {
$elemMatch: {
id: req.params.sectionId
}
},
'sections.box': {
$elemMatch: {
_id: el.id
}
},
}, {
$set: {
'sections.$[outer].box.$[inner].position': el.position
}
}, {
arrayFilters: [{
'outer.id': req.params.sectionId
}, {
'inner._id': el.id
}],
upsert: false,
});
}
But this is not the best method, it hits DB multiple times.
so I need to optimize this code with mongoose query itself.
May be using $set / $push.I don't know any exact methods.
So basically we need to remove the external for loop and make it work with mongoose itself.This is my requirement.
Thanks in advance for all the support.
There are 2 methods for doing it.
bulkWrite
const bulkOps = [];
req.body.forEach((el) => {
const upsertDoc = {
updateOne: {
filter: {
_id: req.params.workspaceId,
sections: {
$elemMatch: {
id: req.params.sectionId
}
},
'sections.box': {
$elemMatch: {
_id: el.id
}
},
},
update: {
$set: {
'sections.$[outer].box.$[inner].position': el.position
}
},
arrayFilters: [{
'outer.id': req.params.sectionId
}, {
'inner._id': el.id
}],
upsert: false,
}
};
bulkOps.push(upsertDoc);
});
const result = await this.model.collection.bulkWrite(bulkOps);
bulkUpdate
const bulkUpdate = this.model.collection.initializeUnorderedBulkOp();
req.body.forEach((el) => {
bulkUpdate.find({
_id: req.params.workspaceId,
sections: { $elemMatch: { id: req.params.sectionId } },
'sections.box': { $elemMatch: { _id: el.id } },
}).arrayFilters([{ 'outer.id': req.params.sectionId }, { 'inner._id': el.id }])
.updateOne({ $set: { 'sections.$[outer].box.$[inner].position': el.position }
});
});
await bulkUpdate.execute();

How to lookup subquery documents with another collection moongoose

I need to join user collections two times as same user will post product and purchased user details as sub document.
Product Schema:
{
product_title: String,
product_desc: String,
Product_purchased:[
{
userid: mongoose.Schema.ObjectId,
purchased_date: Date
}]
posteduserId: mongoose.Schema.ObjectId
}
Users Schema:
{
_id: userId,
name: String,
Pic: String
}
Example document:
[
{
"product_title":"title",
"product_desc":"desc",
"Product_purchased":[
{
"userid":"5d4hvh7duc7c7c8d9scbe",
"name":"name",
"Pic":"url",
"purchased_date":"Date"
},
{
"userid":"5d4hvh7duc7c7c8d9scbe",
"name":"name",
"Pic":"url",
"puchased_date":"Date"
}
],
"posteduserId": "5d4hvh7duc7c7c8d9scbe",
"userid": "5d4hvh7duc7c7c8d9scbe",
"name": "name",
"pic": "url",
}
]
Join same user table with posted userid and subarray of purchased userIds.
Please help me how to crack this one, Thanks in advance.
First you need to fix your Product schema like this to include the ref field:
const mongoose = require("mongoose");
const ProductSchema = new mongoose.Schema({
product_title: String,
product_desc: String,
Product_purchased: [
{
userid: {
type: mongoose.Schema.ObjectId,
ref: "User"
},
purchased_date: Date
}
],
posteduserId: {
type: mongoose.Schema.ObjectId,
ref: "User"
}
});
module.exports = mongoose.model("Product", ProductSchema);
I setup user model like this:
const mongoose = require("mongoose");
const UserSchema = new mongoose.Schema({
name: String,
Pic: String
});
module.exports = mongoose.model("User", UserSchema);
The ref User value must match the model name User in the user model.
Then you need to populate two times like this:
router.get("/products", async (req, res) => {
const result = await Product.find({})
.populate("Product_purchased.userid")
.populate("posteduserId");
res.send(result);
});
Let's say you have this 3 users:
{
"_id": "5e133deb71e32b6a68478ab4",
"name": "user1 name",
"Pic": "user1 pic",
"__v": 0
},
{
"_id": "5e133df871e32b6a68478ab5",
"name": "user2 name",
"Pic": "user2 pic",
"__v": 0
},
{
"_id": "5e133e0271e32b6a68478ab6",
"name": "user3 name",
"Pic": "user3 pic",
"__v": 0
}
And this product:
{
"_id": "5e133e9271e32b6a68478ab8",
"product_title": "product1 title",
"product_desc": "product1 description",
"Product_purchased": [
{
"purchased_date": "2020-01-06T14:02:14.029Z",
"_id": "5e133e9271e32b6a68478aba",
"userid": "5e133df871e32b6a68478ab5"
},
{
"purchased_date": "2020-01-06T14:02:14.029Z",
"_id": "5e133e9271e32b6a68478ab9",
"userid": "5e133e0271e32b6a68478ab6"
}
],
"posteduserId": "5e133deb71e32b6a68478ab4",
"__v": 0
}
The result will be:
[
{
"_id": "5e133e9271e32b6a68478ab8",
"product_title": "product1 title",
"product_desc": "product1 description",
"Product_purchased": [
{
"purchased_date": "2020-01-06T14:02:14.029Z",
"_id": "5e133e9271e32b6a68478aba",
"userid": {
"_id": "5e133df871e32b6a68478ab5",
"name": "user2 name",
"Pic": "user2 pic",
"__v": 0
}
},
{
"purchased_date": "2020-01-06T14:02:14.029Z",
"_id": "5e133e9271e32b6a68478ab9",
"userid": {
"_id": "5e133e0271e32b6a68478ab6",
"name": "user3 name",
"Pic": "user3 pic",
"__v": 0
}
}
],
"posteduserId": {
"_id": "5e133deb71e32b6a68478ab4",
"name": "user1 name",
"Pic": "user1 pic",
"__v": 0
},
"__v": 0
}
]

how to retrieve data from 3 mongoose sachems in custom order

I'm using node, express, mongoose for my back-end. I created User schema as follows,
const mongoose = require('mongoose');
const addressSchema = mongoose.Schema({
_id: mongoose.Schema.Types.ObjectId,
no: { type: String },
firstStreet: { type: String },
secondStreet: { type: String },
city: { type: String, required: true },
district: { type: String }
})
const contactDetailsSchema = mongoose.Schema({
_id: mongoose.Schema.Types.ObjectId,
landNumber: { type: String },
mobileNumber: { type: String },
momNumber: { type: String },
dadNumber: { type: String },
gardianNumber: { type: String }
})
const userSchema = mongoose.Schema({
_id: mongoose.Schema.Types.ObjectId,
email: {
type: String,
required: true,
unique:true,
lowercase: true,
match: /[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*#(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?/
},
password: { type: String, required: true },
role: { type: String, required: true },
fullName: { type: String, required: true },
batch: { type: Number, required: true },
subject: [{
type: String
}],
school: { type: String, required: true },
birthday: { type: String },
address: { type: mongoose.Schema.Types.ObjectId, ref:'User' },
contactDetails: { type: mongoose.Schema.Types.ObjectId, ref:'User' },
stream: { type: String },
});
module.exports = {
user: mongoose.model('User', userSchema),
address: mongoose.model('Address', addressSchema),
contactDetails: mongoose.model('ContactDetails', contactDetailsSchema)
};
and I created a GET route to retrieve data from all users. I store these data in three separate mongoDB collections with same _id. And I want to get those all User data.
my User GET route is like this,
const userModels = require('../models/user');
const User = userModels.user;
const Address = userModels.address;
const ContactDetails = userModels.contactDetails;
router.get('/', (req, res) =>{
User
.find()
.exec()
.then(docs => {
console.log(docs);
const responce1 = {
count: docs.length,
Users: docs.map(doc => {
return {
Message: 'User Details',
Id: doc._id,
Email: doc.email,
Role: doc.role,
Full_Name: doc.fullName,
Batch: doc.batch,
Subject: doc.subject,
School: doc.school,
Birthday: doc.birthday,
Stream: doc.stream,
request: {
type: 'get',
url: 'http://localhost:3000/user/' +doc._id
}
}
})
}
Address
.find()
.exec()
.then(docs => {
console.log(docs)
responce2 = {
count: docs.length,
Address: docs.map(doc => {
return {
Message: 'Address',
_id: doc._id,
Address: doc.city,
First_Street: doc.firstStreet,
Second_Street: doc.secondStreet,
city: doc.city,
District: doc.district,
}
})
}
})
.catch(err => {
console.log(err);
res.status(500).json({
error: err
});
});
ContactDetails
.find()
.exec()
.then(docs => {
console.log(docs)
responce3 = {
count: docs.length,
ContactDetails: docs.map(doc => {
return {
Message: 'Contact Details',
_id: doc._id,
Land_Number: doc.landNumber,
Mobile_Number: doc.mobileNumber,
Mom_Number: doc.momNumber,
Dad_Number: doc.dadNumber,
Gardian_Number: doc.gardianNumber,
}
})
}
res.status(200).json([responce1,responce2,responce3]);
})
.catch(err => {
console.log(err);
res.status(500).json({
error: err
});
});
})
.catch(err => {
console.log(err);
res.status(500).json({
error: err
});
});
});
I get data like this,
[
{
"count": 3,
"Users": [
{
"Message": "User Details",
"Id": "5b8e68fb9c898543b4970628",
"Email": "new2#gmail.com",
"Role": "student",
"Full_Name": "Dinusha",
"Batch": 16,
"Subject": [
"ICT"
],
"School": "School",
"Birthday": "1996/10/23",
"Stream": "English",
"request": {
"type": "get",
"url": "http://localhost:3000/user/5b8e68fb9c898543b4970628"
}
},
{
"Message": "User Details",
"Id": "5b8e68fd9c898543b4970629",
"Email": "new3#gmail.com",
"Role": "student",
"Full_Name": "Dinusha",
"Batch": 16,
"Subject": [
"ICT"
],
"School": "School",
"Birthday": "1996/10/23",
"Stream": "English",
"request": {
"type": "get",
"url": "http://localhost:3000/user/5b8e68fd9c898543b4970629"
}
},
{
"Message": "User Details",
"Id": "5b8f52e707c299266c0a6b97",
"Email": "new4#gmail.com",
"Role": "student",
"Full_Name": "Dinusha",
"Batch": 16,
"Subject": [
"ICT"
],
"School": "School",
"Birthday": "1996/10/23",
"Stream": "English",
"request": {
"type": "get",
"url": "http://localhost:3000/user/5b8f52e707c299266c0a6b97"
}
}
]
},
{
"count": 3,
"Address": [
{
"Message": "Address",
"_id": "5b8e68fb9c898543b4970628",
"Address": "city",
"city": "city",
"District": "rathnapura"
},
{
"Message": "Address",
"_id": "5b8e68fd9c898543b4970629",
"Address": "city",
"city": "city",
"District": "rathnapura"
},
{
"Message": "Address",
"_id": "5b8f52e707c299266c0a6b97",
"Address": "city",
"city": "city",
"District": "rathnapura"
}
]
},
{
"count": 3,
"ContactDetails": [
{
"Message": "Contact Details",
"_id": "5b8e68fb9c898543b4970628",
"Land_Number": "072846",
"Mobile_Number": "7368438",
"Mom_Number": "7364738",
"Dad_Number": "648364"
},
{
"Message": "Contact Details",
"_id": "5b8e68fd9c898543b4970629",
"Land_Number": "072846",
"Mobile_Number": "7368438",
"Mom_Number": "7364738",
"Dad_Number": "648364"
},
{
"Message": "Contact Details",
"_id": "5b8f52e707c299266c0a6b97",
"Land_Number": "072846",
"Mobile_Number": "7368438",
"Mom_Number": "7364738",
"Dad_Number": "648364"
}
]
}
]
but I need to get data of every User like in this form
[
"Users":
{
"Message": "User Details",
"Id": "5b8e68fb9c898543b4970628",
"Email": "new2#gmail.com",
"Role": "student",
"Full_Name": "Dinusha",
"Batch": 16,
"Subject": [
"ICT"
],
"School": "School",
"Birthday": "1996/10/23",
"Stream": "English",
"request": {
"type": "get",
"url": "http://localhost:3000/user/5b8e68fb9c898543b4970628"
}
},
"Address":
{
"Message": "Address",
"_id": "5b8e68fb9c898543b4970628",
"Address": "city",
"city": "city",
"District": "rathnapura"
},
"ContactDetails":
{
"Message": "Contact Details",
"_id": "5b8e68fb9c898543b4970628",
"Land_Number": "072846",
"Mobile_Number": "7368438",
"Mom_Number": "7364738",
"Dad_Number": "648364"
},
]
can I get those data like that.
how to get data from mongodb as that custom form.
Use aggregate method and $lookup
https://mongoosejs.com/docs/api.html#aggregate_Aggregate-lookup

Resources