I am new to Mongo db/Mongoose, this question is about mongoose and relationships between collections, I know there's a lot of tutorials about how to make this work but still not able to understand an easy way to make this work. I have a two models:
This is the main model:
'use strict';
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
var CategorySchema = new Schema({
name : String,
info : String,
items : [{ type: Schema.Types.ObjectId, ref: 'Item' }]
});
var itemsSchema = Schema({
name : String,
description : String,
price : Number
});
var Item = mongoose.model('Item', itemsSchema);
module.exports = mongoose.model('Category', CategorySchema);
I need to populate items array inside category collection and create the relationship between the two collections.
When I a post from postman I can see the items array getting created but I am not able to populate the array.
If I do get categories, this is the response:
[
{
"_id": "564120be4123198a1f93feb5",
"name": "Classic",
"info": "this is the info",
"__v": 0,
"items": []
},
{
"_id": "5641220b02968e901f678ff5",
"name": "Classic",
"info": "this is the info",
"__v": 0,
"items": []
}
]
This is the put result to api/categories/
{
"_id": "564120be4123198a1f93feb5",
"name": "test again",
"info": "this is the info",
"__v": 1,
"items": []
}
Desired output:
{
"_id": "564120be4123198a1f93feb5",
"name": "test again",
"info": "this is the info",
"__v": 1,
"items": [
{
"_id": "some id"
"name": "name",
"description": "lorem ipsup"
},
{
"_id": "some id"
"name": "name",
"description": "lorem ipsup"
},
{
"_id": "some id"
"name": "name",
"description": "lorem ipsup"
},
]
}
Even if you've a reference in Category, you should use populate method to inform mongoose that you want him to retrieve the referenced items.
Something like:
var Category = require('./category.model');
Category.find().populate("items");
if you want to populate only one field of item model you can add it ine parameter of populate:
Category.find().populate("items","name");
I don't know what you want to achieve but it seems to me that the other way could be more beneficial (having a reference to category into item model).
Related
[
{
"id": "628ba44f5a6de600071d16fa",
"#baseType": "LogicalResource",
"isBundle": false,
"isMNP": false,
"businessType": [],
"category": [
{
"id": "628ba3ef5a6de600071d165f",
"name": "Starterpack2",
"description": "Starterpack2",
"code": "RC17",
"version": 2
}}]
now i need to check and print the JSON Object inside the JSON Array if category is present then it should print and in future if category is changed according to that if we pass parameter the output should print we don't hard code the code
i have tried by using key values it is coming but if the key value changes it is not printing the object
EX:-
[
{
"id": "628ba44f5a6de600071d16fa",
"#baseType": "LogicalResource",
"isBundle": false,
"isMNP": false,
"businessType": [],
"category": [
{
"id": "628ba3ef5a6de600071d165f",
"name": "Starterpack2",
"description": "Starterpack2",
"code": "RC17",
"version": 2
}}]
in the above code i have printed category object but if category changed to categories it is not printing so i want a code which can read the code and based on parameters user giving it should be print the output
Try this.
For Example:
let a = [{"id": "628ba44f5a6de600071d16fa","category": [
{
"id": "628ba3ef5a6de600071d165f",
"name": "Starterpack2",
"description": "Starterpack2",
"code": "RC17",
"version": 2
}]}]
function print (values){return (a[0][`${values}`])}
//now just pass any name like "category" or in future "categories"
print("category") //this will retrun the array.
Now modify with your requirements.
It seems you want to get the value of the key(that can be parameterized).
const jsonArray = [
{
"id": "628ba44f5a6de600071d16fa",
"#baseType": "LogicalResource",
"isBundle": false,
"isMNP": false,
"businessType": [],
"category": [
{
"id": "628ba3ef5a6de600071d165f",
"name": "Starterpack2",
"description": "Starterpack2",
"code": "RC17",
"version": 2
}
]
}
];
const parameter = "category";
const result = jsonArray.find(({ [parameter]: value }) => value);
if (result) {
console.log(result);
} else {
console.log(`No object found with ${parameter}`);
}
If this is not what you are looking for, then please add your code snippet for better understanding.
I am going through a challenge from devchallenges.io, Shoppingify challenge. Having read the prompt, I proceeded to create a model which has the following format when a request is made.
{
"user": 1,
"_id": 3393220221,
"name": Chicken,
"category": "Meat",
"note": "This is an example note",
"image_url": "www.exampleurl.com"
}
The issue I'm having is that the component expects the object in the following format.
{
"category": "Meat",
"items": [
{
"user": 1,
"_id": "3393220221",
"name": "Chicken",
"note": "This is an example note",
"image_url": "www.exampleurl.com"
}
]
}
The link to the challenge is https://devchallenges.io/challenges/mGd5VpbO4JnzU6I9l96x for visual reference.
I'm struggling with how to modify the object response from the request. I want to be able to find occurances of the same category name and push the items onto a new object as shown.
const users = [
{
"user": 1,
"_id": 3393220221,
"name": "Chicken",
"category": "Meat",
"note": "This is an example note",
"image_url": "www.exampleurl.com"
}
];
function modifyUserObject(users) {
const result = {};
users.forEach(user => {
if (!result[user]) {
result[user] = {
category: user.category,
items: []
}
}
//code here..if want to remove user properties like user
result[user].items.push(user);
});
return Object.values(result);
}
modifyUserObject(users);
Hope this will be helpful! Happy coding...
The value Chicken is not defined. Is this a typing error by you? Anyway this should do the trick:
const obj = {
user: 1,
_id: 3393220221,
name: "Chicken",
category: "Meat",
note: "This is an example note",
image_url: "www.exampleurl.com",
};
function createObj(arg) {
let result = {
category: arg.category,
items: [
{
user: arg.user,
_id: arg._id,
name: arg.name,
note: arg.note,
image_url: arg.image_url,
},
],
};
return result;
}
console.log(createObj(obj));
Edit:
If you want to create a new object that is not related to the old one (deep copy) you need to do JSON.parse(JSON.stringify(obj)) to not change the values of the original object.
I am banging my head against the wall on this...
SEE UPDATE 1 (below) !
I am merging two collections together... I looked at this example ( and ~several~ other examples here on SO ... )
https://docs.mongodb.com/manual/reference/operator/aggregation/lookup/#lookup-single-equality
I think I am really close, but my expected results are not the same as what I would expect out of the example.
Here is the schema for 'Event'
const EventSchema = new Schema({
name: {type: String, required: true},
})
Here is some 'Event' data
[
{
"_id": "5e8e4fcf781d96df5c1f5358",
"name": "358 Event"
},
{
"_id": "5e8e55c5a0f5fc1431453b5f",
"name": "b5f Event"
}
]
Here is 'MyEvent' schema:
const MyEventSchema = new Schema({
userId: {type: Schema.Types.ObjectId, required: true},
eventId: {type: Schema.Types.ObjectId, required: true},
})
Here is some 'MyEvent' data
[
{
"_id": "5e8f4ed2ddab5e3d04ff30b3",
"userId": "5e6c2dddad72870c84f8476b",
"eventId": "5e8e4fcf781d96df5c1f5358",
}
]
Here is my code ( the code is wrapped in a promise so it returns resolve and reject with data )
var agg = [
{
$lookup:
{
from: "MyEvent",
localField: "_id",
foreignField: "eventId",
as: "userIds"
}
}
];
Event.aggregate(agg)
.then( events => {
return resolve(events);
})
.catch(err => {
return reject(null);
})
Here are my results,
[
{
"_id": "5e8e4fcf781d96df5c1f5358",
"name": "358 Event",
"__v": 0,
"UserIds": []
},
{
"_id": "5e8e55c5a0f5fc1431453b5f",
"name": "b5f Event",
"__v": 0,
"UserIds": []
}
]
I expect to see UserIds filled in for event '358 Event', like this
What am I missing ???
[
{
"_id": "5e8e4fcf781d96df5c1f5358",
"name": "358 Event",
"__v": 0,
"UserIds": [
{"userId": "5e6c2dddad72870c84f8476b"}
]
},
{
"_id": "5e8e55c5a0f5fc1431453b5f",
"name": "b5f Event",
"__v": 0,
"UserIds": []
}
]
UPDATE 1
I found a mongo playground and what I have works there, but it doesn't work in my code ??
https://mongoplayground.net/p/fy-GP_yx5j7
In case the link breaks, here is configuration: * select 'bson multiple collections'
db={
"collection": [
{
"_id": "5e8e4fcf781d96df5c1f5358",
"name": "358 Event"
},
{
"_id": "5e8e55c5a0f5fc1431453b5f",
"name": "b5f Event"
}
],
"other": [
{
"_id": "5e8f4ed2ddab5e3d04ff30b3",
"userId": "5e6c2dddad72870c84f8476b",
"eventId": "5e8e4fcf781d96df5c1f5358",
}
]
}
Here is Query:
db.collection.aggregate([
{
$lookup: {
from: "other",
localField: "_id",
foreignField: "eventId",
as: "userIds"
}
}
])
Here is the result:
[
{
"_id": "5e8e4fcf781d96df5c1f5358",
"name": "358 Event",
"userIds": [
{
"_id": "5e8f4ed2ddab5e3d04ff30b3",
"eventId": "5e8e4fcf781d96df5c1f5358",
"userId": "5e6c2dddad72870c84f8476b"
}
]
},
{
"_id": "5e8e55c5a0f5fc1431453b5f",
"name": "b5f Event",
"userIds": []
}
]
any suggestions as to why this doesn't work in my code... but works in the playground?
UPDATE 2
I found this:
Need a workaround for lookup of a string to objectID foreignField
UPDATE 3
I have changed the schema to use ObjectId for ids now
still doesn't work
And they are ObjectIds :
RESOLUTION:
So the real answer was a combination of Update 2 and Update 3 and using the right collection name in the lookup.
Update 2 is pretty much my very same question... just using different table names
Update 3 is the correct way to solve this issue.
Mohammed Yousry pointed out the collection name might be wrong... so I looked at my schema and I did have it wrong - changed the name to the right name (along with ObjectId types) and it worked !
It seems there's a typo in from property in $lookup, MyEvent maybe not the collection name
db.collection.aggregate([
{
$lookup: {
from: "MyEvent", // here is the issue I think, check the collection name and make sure that it matches the one you write here
localField: "_id",
foreignField: "eventId",
as: "userIds"
}
}
])
in mongo playground you attached in the question, if you change the 'other' in the $lookup to anything else, or make a typo in it .. like others instead of other, you will face the same issue
so check that there is no typo in the word MyEvent that you populate from
How to access the name property of the inside the subjects array?
The database is mongodb.
Change for the course model is not possible.
The course model :
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const SubjectSchema = new Schema({
name : {
type : String
},
description : {
type : String
},
amount : {
type : Number
},
});
//course schema
const CourseSchema = new Schema({
name: {
type : String
},
code : {
type: String
},
passMark : {
type : Number
},
lectureInCharge : {
type : String
},
subjects : {
type : [SubjectSchema]
}
});
//creating model
const Course = mongoose.model('course', CourseSchema);
module.exports = Course;
code which i want access to the subject details of a course?
I want to display the course details with subject details which is inside the
course details. But subjects are inside an array which is assigned to the subject property of the course object.
It is a react interface.
const courses = this.state.courses;
const updatedCourse = courses.map(function (data, index) {
return (
<div key={index}>
<p> Name : {data.name}</p>
<p> Code : {data.code}</p>
<p> Pass Mark : {data.passMark}</p>
<p> lecture in charge : {data.lectureInCharge}</p>
<p> Subjects : </p>
//Here i want aceess the ame property of the inside the
subjects array?
<p> Subject name : {data.subjects.name}</p>
</div>
)
});
The json of the which retrieve from the database looks like this.
Included to get an idea how the database looks like.
[
{
"_id": "5cf348111b0ffd3bc02304b8",
"name": "Software Engineering",
"code": "SE2019",
"passMark": 75,
"lectureInCharge": "Jhon Smith",
"subjects": [
{
"_id": "5cf348111b0ffd3bc02304b9",
"name": "Computer Architecture",
"description": "PC Architecture x86 and x64",
"amount": 2500
}
],
"__v": 0
},
{
"_id": "5cf358991b0ffd3bc02304ba",
"name": "Computer Networking",
"code": "CN2019",
"passMark": 75,
"lectureInCharge": "Jimmy Perera",
"subjects": [
{
"_id": "5cf358991b0ffd3bc02304bc",
"name": "Wireless Communications",
"description": "Introduction to Wireless Communications",
"amount": 5000
},
{
"_id": "5cf358991b0ffd3bc02304bb",
"name": "Network Technology Project",
"description": "Introduction to Network Technology Project",
"amount": 7000
}
],
"__v": 0
},
{
"_id": "5cf3593d1b0ffd3bc02304c0",
"name": "IM",
"code": "IM2019",
"passMark": 75,
"lectureInCharge": "IMIM Jimmy Perera",
"subjects": [
{
"_id": "5cf3593d1b0ffd3bc02304c2",
"name": "IM Wireless Communications",
"description": " IM Introduction to Wireless Communications",
"amount": 3000
},
{
"_id": "5cf3593d1b0ffd3bc02304c1",
"name": "IM Network Technology Project",
"description": "IM Introduction to Network Technology Project",
"amount": 7700
}
],
"__v": 0
}
]
Since it's an array, you'll need an inner loop (probably another map):
const courses = this.state.courses;
const updatedCourse = courses.map(function (data, index) {
return (
<div key={index}>
<p> Name : {data.name}</p>
<p> Code : {data.code}</p>
<p> Pass Mark : {data.passMark}</p>
<p> lecture in charge : {data.lectureInCharge}</p>
<p> Subjects : </p>
{data.subjects.map(({name}, i) => ( // <===
<p key={i}> Subject name : {name}</p> // <===
)}
</div>
);
});
I am working with facebook JS SDK which returns user's information in JSON format. I know how to get the response like response.email which returns email address. But how to get an element from a nested array object? Example: user's education history may contain multiple arrays and each array will have an element such as "name" of "school". I want to get the element from the last array of an object.
This is a sample JSON I got:-
"education": [
{
"school": {
"id": "162285817180560",
"name": "Jhenaidah** School"
},
"type": "H**hool",
"year": {
"id": "14404**5610606",
"name": "2011"
},
"id": "855**14449421"
},
{
"concentration": [
{
"id": "15158**968",
"name": "Sof**ering"
},
{
"id": "20179020**7859",
"name": "Dig**ty"
}
],
"school": {
"id": "10827**27428",
"name": "Univer**g"
},
"type": "College",
"id": "9885**826013"
},
{
"concentration": [
{
"id": "108196**810",
"name": "Science"
}
],
"school": {
"id": "2772**996993",
"name": "some COLLEGE NAME I WANT TO GET"
},
"type": "College",
"year": {
"id": "1388*****",
"name": "2013"
},
"id": "8811215**16"
}]
Let's say I want to get "name": "some COLLEGE NAME I WANT TO GET" from the last array. How to do that with Javascript? I hope I could explain my problem. Thank you
Here is a JsFiddle Example
var json = '{}' // your data;
// convert to javascript object:
var obj = JSON.parse(json);
// get last item in array:
var last = obj.education[obj.education.length - 1].school.name;
// result: some COLLEGE NAME I WANT TO GET
If your json above was saved to an object called json, you could access the school name "some COLLEGE NAME I WANT TO GET" with the following:
json.education[2].school.name
If you know where that element is, then you can just select it as already mentioned by calling
var obj = FACEBOOK_ACTION;
obj.education[2].school.name
If you want to select specifically the last element, then use something like this:
obj.education[ obj.education.length - 1 ].scool.name
Try this,
if (myData.hasOwnProperty('merchant_id')) {
// do something here
}
where JSON myData is:
{
amount: "10.00",
email: "someone#example.com",
merchant_id: "123",
mobile_no: "9874563210",
order_id: "123456",
passkey: "1234"
}
This is a simple example for your understanding. In your scenario of nested objects, loop over your JSON data and use hasOwnProperty to check if key name exists.