How to populate array inside array of object in mongoose - reactjs

i have a classShcema,inside my marksSchema i have class property i.e populated from classSchema.note that classSchema has subject and it is populate from subjectSchema.
const classSchemaDef = new mongoose.Schema({
classes:{type:Number},
subject:[{
type:mongoose.Types.ObjectId,
ref:'subject',
require:true,
default:null
}],
section:[String],
created_by:commonSchema.created_by,
},commonSchema.Trigger)
below is the Marksschema that has class in it. the class is populated but subject is not being populate.
const MarksSchemaDef = new mongoose.Schema(
{
student: {
type: mongoose.Types.ObjectId,
required: true,
ref: "student",
default: null,
},
marks_obtain: [
{
class: {
type: mongoose.Types.ObjectId,
ref: "class",
required: true,
default: null,
},
subject: {
type: mongoose.Types.ObjectId,
ref: "subject",
},
marks: {
type: Number,
required: true,
},
created_by: commonSchema.created_by,
},
],
},
commonSchema.Trigger
);
below is the code to retrive data from marksModel and populate the data.
getAllMarks = async (skip, limit) => {
return await MarksModel.find()
.skip(skip)
.limit(limit)
.populate("student")
.populate("marks_obtain.class")
.populate("marks_obtain.class.subject")
.populate("marks_obtain.subject");
}
below is the response data i got
{
"_id": "63ce6eb551a5815f8662fd87",
"student": {
"parentname": {
"fullname": "mohan shrestha",
"phone": 868594
},
"_id": "63c80a2912d13e1af652df71",
"studentname": "mogina shrestha",
"class": 8,
"image": "localhost:3000/pic.jpg",
"address": "dhanusmode",
"phone": 2675442,
"section": "a",
"created_by": null,
"__v": 0
},
"marks_obtain": [
{
"class": {
"_id": "63a6a17590f43440d694cedb",
"classes": 8,
"subject": [
"63a42fbd14407d172f07586d",
"63a42fd814407d172f075873"
],
"section": [
"a",
"b",
"c"
],
"created_by": null,
"__v": 0
},
"subject": {
"_id": "63a42fd814407d172f075873",
"subjectname": "grammer",
"__v": 0
},
"marks": 55,
"created_by": null,
"_id": "63ce6eb551a5815f8662fd88"
}
],
"__v": 0
}
],

Related

Adding elements within Object TypeScript

Hello everyone i have dynamically expanding object which consists of a 2 x dimensional array. I
try to add in field label:{ } new key:value {"hg":"Hg"} object.
object JSON:
[
{
"callbackQueryData": "tNLQy3VcX",
"method": {
"value": "",
"property": "",
"linkUrl": "",
"inside": null,
"type": "NEXT_PAGE",
"nextId": "Cll8xZbVo6",
"validation": null,
"calendar": null,
"condition": null,
"api": null,
"pagination": null
},
"label": {
"en": "New button"
}
},
{
"callbackQueryData": "qntufUVhz",
"label": {
"en": "New button"
},
"method": {
"value": "",
"property": "",
"linkUrl": "",
"inside": null,
"type": "NEXT_PAGE",
"nextId": "",
"validation": null,
"calendar": null,
"condition": null,
"api": null,
"pagination": null
}
}
],
[
{
"callbackQueryData": "cx46ECYG9",
"label": {
"en": "New button"
},
"method": {
"value": "",
"property": "",
"linkUrl": "",
"inside": null,
"type": "NEXT_PAGE",
"nextId": "",
"validation": null,
"calendar": null,
"condition": null,
"api": null,
"pagination": null
}
}
],
[
{
"callbackQueryData": "uHp5yd3Li",
"label": {
"en": "New button"
},
"method": {
"value": "",
"property": "",
"linkUrl": "",
"inside": null,
"type": "NEXT_PAGE",
"nextId": "",
"validation": null,
"calendar": null,
"condition": null,
"api": null,
"pagination": null
}
}
],
[]
]
I try cast it to simple array and via forEach() addressing everyone elements button:any and to add object which i need. But Spread syntax(...) can't find argument forEach().Or I'm doing it completely wrong.
let arrayButton:IBotButton[][] = ([] as IBotButton[][]).concat(...page.callbacks)//create simple array
arrayButton.forEach((button:any)=>{
...button,
label: { ...button.label, [languageSelect]: buttonText }
})
Assume your arrayButton looks like this:
const arrayButton: IBotButton[][] = [
[
{
label: { "en": "new Button-1" }
// ...
},
{
label: { "en": "new Button-2" }
// ...
},
//...
],
[
//...
]
];
And have these variables:
const languageSelect: string = "jp";
const buttonText: string = "new Button-3";
Then you could modify the label by following code:
// arrayButton is 2d array
arrayButton.forEach((array) => {
// array is 1d array
array.forEach((button, buttonIdx) => {
array[buttonIdx] = {
...button,
label: {
...button.label,
[languageSelect]: buttonText,
},
};
});
});

MongoDB $push in Array of Array Error: No value exists in scope for the shorthand property 'elements'

I wish to add data into Elements but get error. How to solve this mongodb/typescript problem?
Attempt 1 Error: No value exists in scope for the shorthand property 'elements'. Either declare one or provide an initializer.ts(18004)
Attempt 1
async add<T extends { id: string; parentID: string, elementNum: number, name: string, link: string}>(collectionName: string, args: T) {
const db = await this.getDB();
const collection = db.collection(collectionName);
return new Promise((resolve, reject) => {
collection.updateOne({ id: args.id }, {$push: {elements[args.elementNum]: {id: uuid(), name: args.name, link: args.link, elements: [] }}}, (err, res) => {
if (err) {
reject(err);
}
resolve(res);
});
});
}
Attempt 2
changed the following
collection.updateOne({ id: args.id }, {$push: {elements: {id: uuid(), name: args.name, link: args.link, elements: [] }}},
Attempt 2 results in Null added in the end
{
"id": "1",
"name": "wk1",
"iconFile": "icon.png",
"elements": [
[
{
"id": "2",
"name": "element2",
"link": "https",
"elements": [
{
"id": "1",
"name": "element1",
"link": "https:"
}
]
}
],
[
{
"id": "3",
"name": "element3",
"link": "https://",
"elements": [
{
"id": "4",
"name": "w",
"link": "http:/"
}
]
}
],
[
{
"id": "3",
"name": "element3",
"link": "https://",
"elements": [
{
"id": "4",
"name": "w",
"link": "http://"
}
]
},
{
"id": "3",
"name": "element3",
"link": "https://",
"elements": [
{
"id": "4",
"name": "w",
"link": "http://www."
}
]
}
],
null,
]
}
What I want to achieve is the following
{
"id": "1",
"name": "wk1",
"iconFile": "icon.png",
"elements": [
[
{
"id": "2",
"name": "element2",
"link": "https",
"elements": [
{
"id": "1",
"name": "element1",
"link": "https:"
}
]
},
{
"id": "newid",
"name": "newname",
"link": "newlink"
"elements":[]
}
],
[
{
"id": "3",
"name": "element3",
"link": "https://",
"elements": [
.......
]
}
Demo - https://mongoplayground.net/p/Dnmg3lL2891
Use - $[]
The all positional operator $[] indicates that the update operator
should modify all elements in the specified array field.
The $[] operator has the following form:
{ <update operator>: { "<array>.$[]" : value } }
db.collection.update({ _id: 1, "add.id": "1"},
{ $push: { "add.$[].elements": { id: "3", name: "a", link: "" } } })
Demo to push array instead of object - https://mongoplayground.net/p/dh3NSutIv4-
db.collection.update({ _id: 1, "add.id": "1"},
{ $push: { "add.$[].elements": [{ id: "3", name: "a", link: "" }] } })
const args = {};
args.elementNum = 0;
const update = {
[`add.$[].elements.${args.elementNum}`]: {
a: 1
}
};
console.log(update);
//collection.updateOne({ id: args.id }, update); // use like this

Search in Embedded Documents in MongoDB?

I have document as shown
[
{
"Users": [
{
"Name": "Kartikey Vaish",
"_id": "1",
},
{
"Name": "Witcher Proxima",
"_id": "2",
}
],
"_id": "12",
},
{
"Users": [
{
"Name": "Witcher Proxima",
"_id": "2",
},
{
"Name": "Saga",
"_id": "4",
}
],
"_id": "13",
}
]
I want to search for those documents whose Users array has that particular ID
For Example if
ID == 1 // should return
[
{
"Users": [
{
"Name": "Kartikey Vaish",
"_id": "1",
},
{
"Name": "Witcher Proxima",
"_id": "2",
}
],
"_id": "12",
}
]
ID == 2 // should return
[
{
"Users": [
{
"Name": "Kartikey Vaish",
"_id": "1",
},
{
"Name": "Witcher Proxima",
"_id": "2",
}
],
"_id": "12",
},
{
"Users": [
{
"Name": "Witcher Proxima",
"_id": "2",
},
{
"Name": "Saga",
"_id": "4",
}
],
"_id": "13",
}
]
ID == 4 // should return
[
{
"Users": [
{
"Name": "Kartikey Vaish",
"_id": "1",
},
{
"Name": "Saga",
"_id": "4",
}
],
"_id": "13",
}
]
As you can see from above my query should return only those objects whose "Users" array contains an object with given ID. I tried this but it doesn't work.
const chats = await Chats.find({
Users: { $elemMatch: { _id: "1" } },
});
// this returns an empty array
const chats = await Chats.find({
Users: { $elemMatch: { Name: "Kartikey Vaish" } },
});
// this returns
[
{
"Users": [
{
"Name": "Kartikey Vaish",
"_id": "1",
},
{
"Name": "Witcher Proxima",
"_id": "2",
}
],
"_id": "12",
}
]
What am I doing wrong here?
Is it something related to _id paramter?
EDIT:
My Chats Schema looks like this -
const Chats = mongoose.model(
"Chats",
new mongoose.Schema({
Users: {
type: Array,
required: true,
default: [],
},
})
);
Update your schema as shown below
const Chats = mongoose.model(
"Chats",
new mongoose.Schema({
Users: [{
_id: {
type: String,
required: true, // Include only if needed!
unique: true // Include only if needed!
},
Name: {
type: String,
index: true // Include only if needed!
}
}]
})
);
If you do not explicitly mention _id MongoDB will create _id field as ObjectId.

get dynamic data from the slot ? not added resolutionsPerAuthority's dynamic element in the list

I am trying to get dynamic data from the slot
As per documentation and my basic test I am sending directive from launch request as like :
{'version': '1.0', 'response': {'outputSpeech': {'type': 'SSML', 'ssml': '<speak> Hi, welcome to developement dynamic slot. <break time="800ms"/>Please tell me the product name you would be interested in</speak>'}, 'card': {'type': 'Simple', 'title': 'Choose a Medicine.', 'content': 'Pick a Medicine.'}, 'reprompt': {'outputSpeech': {'type': 'SSML', 'ssml': '<speak><break time="5s"/>I am HERE to help You, Please tell me the product and country names you would be interested in.</speak>'}}, 'shouldEndSession': False}, 'directives': [{'type': 'Dialog.UpdateDynamicEntities', 'updateBehavior': 'REPLACE', 'types': [{'name': 'products', 'values': [{'id': 'grnTea', 'name': {'value': 'green tea', 'synonyms': ['matcha']}}, {'id': 'oolTea', 'name': {'value': 'oolong', 'synonyms': ['chinese tea', 'black dragon tea']}}]}]}]}
and when I'm trying to get data which is not statically store in a slot but added in directive slot value.
returns following output :
{ "version": "1.0", "session": { "new": false, "sessionId": "amzn1.echo-api.session.671181ed-1e50-4e4c-b70e-4d854fe7cb78", "application": { "applicationId": "amzn1.ask.skill.c35cd12c-6845-473e-be58-9b1139ee0adb" }, "user": { "userId": "amzn1.ask.account.sadasdsa", "permissions": { "consentToken": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IjEifQ..XyWgyUIjDzzlZ12CR0lbZid6GxwZZYBgarlV-9difbkFjOTxrcvS9lJYWo-Db3wo-fIdXb_jZkCAJBtYPggqnJhLyyC-EDa0_u9aARKthF1_nkbLh5zDOHDb8MyyOYro4BJlqm4XBNd1qyeQUV2M4fdca1YSEnbEun_6kWOKeFRS-14zcwMj5E-MHcBbeDX799A_kay82kS8VGeMhSUsXPTZFrwOKHcFweJTqXFNOkBxME8kAFfS1JB5MNbA3TujVIsIgTBSNQaJeHRksConKt0u06ATrjffzFkcmbxDT5HoJH4NqDgS0y_GdtaeXQM3LJ-MN0-_DMX2QVEaL6kUUw" } } }, "context": { "System": { "application": { "applicationId": "amzn1.ask.skill.c35cd12c-6845-473e-be58-9b1139ee0adb" }, "user": { "userId": "amzn1.ask.account.aasdasdasdasdas", "permissions": { "consentToken": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IjEifQ.asdjaskdhas.XyWgyUIjDzzlZ12CR0lbZid6GxwZZYBgarlV-9difbkFjOTxrcvS9lJYWo-Db3wo-fIdXb_jZkCAJBtYPggqnJhLyyC-EDa0_u9aARKthF1_nkbLh5zDOHDb8MyyOYro4BJlqm4XBNd1qyeQUV2M4fdca1YSEnbEun_6kWOKeFRS-14zcwMj5E-MHcBbeDX799A_kay82kS8VGeMhSUsXPTZFrwOKHcFweJTqXFNOkBxME8kAFfS1JB5MNbA3TujVIsIgTBSNQaJeHRksConKt0u06ATrjffzFkcmbxDT5HoJH4NqDgS0y_GdtaeXQM3LJ-MN0-_DMX2QVEaL6kUUw" } }, "device": { "deviceId": "amzn1.ask.device.ajshdjkhasjkhdkjsahkasdhjasd", "supportedInterfaces": {} }, "apiEndpoint": "https://api.eu.amazonalexa.com", "apiAccessToken": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IjEifQ.asdhjashjdhajsd.RQhzWmnhN9K_dCbsFXBPPoLVzuwe5BWjAruwJNF1pVr11PiygVgQ64W3CNng2sK1thT2tl6r3GuRtG-1133Aw1KPWtMuHElu7CTrFfgAqW8blpK37PJIvPMOUGBw1rbrgCTMdy8Ua7qSFV_Y_wlOJaV3-apDGBqhQKE_-dE-ntWYZuIySlY3l8hBs_66eELS-LiL5DEDJk1hfvC2C6ZFB7A7P8mx4Hb71km-lYaElJS0-FDP0C-LdSp6dCbzV23W4JehtTGL4kJ1JEQgWyuNAAkt_HmPcEYlPp8T5RFceDuVuz-ZZBFyiVKuAN8VmxyFsmnC3SXi4yb3RKm1SCcorg" }, "Viewport": { "experiences": [ { "arcMinuteWidth": 246, "arcMinuteHeight": 144, "canRotate": false, "canResize": false } ], "shape": "RECTANGLE", "pixelWidth": 1024, "pixelHeight": 600, "dpi": 160, "currentPixelWidth": 1024, "currentPixelHeight": 600, "touch": [ "SINGLE" ], "video": { "codecs": [ "H_264_42", "H_264_41" ] } }, "Viewports": [ { "type": "APL", "id": "main", "shape": "RECTANGLE", "dpi": 160, "presentationType": "STANDARD", "canRotate": false, "configuration": { "current": { "video": { "codecs": [ "H_264_42", "H_264_41" ] }, "size": { "type": "DISCRETE", "pixelWidth": 1024, "pixelHeight": 600 } } } } ] }, "request": { "type": "IntentRequest", "requestId": "amzn1.echo-api.request.0f3b51f1-880b-483f-8410-3210e81e5b59", "timestamp": "2020-01-01T11:48:09Z", "locale": "en-IN", "intent": { "name": "productcheck", "confirmationStatus": "NONE", "slots": { "products": { "name": "products", "value": "green tea", "resolutions": { "resolutionsPerAuthority": [ { "authority": "amzn1.er-authority.echo-sdk.amzn1.ask.skill.c35cd12c-6845-473e-be58-9b1139ee0adb.products", "status": { "code": "ER_SUCCESS_NO_MATCH" } } ] }, "confirmationStatus": "NONE", "source": "USER" } } } } }
It's not added resolutions resolutionsPerAuthority's second(dynamic) element in the list.
anybody can help me out from this problem?
I tested your added directive exactly as pasted and the dynamic entity resolved as expected:
"slots": {
"products": {
"name": "products",
"value": "matcha",
"resolutions": {
"resolutionsPerAuthority": [
{
"authority": "amzn1.er-authority.echo-sdk.amzn1.ask.skill.****.products",
"status": {
"code": "ER_SUCCESS_NO_MATCH"
}
},
{
"authority": "amzn1.er-authority.echo-sdk.dynamic.amzn1.ask.skill.****.products",
"status": {
"code": "ER_SUCCESS_MATCH"
},
"values": [
{
"value": {
"name": "green tea",
"id": "grnTea"
}
}
]
}
]
},
"confirmationStatus": "NONE",
"source": "USER"
}
}
Could you share your skill's interaction model to investigate further?

Get inner array value based on condition with other values in mongoose

I have a DB structure as follows:
{
"Title": "AAA",
"Photos": ["/aaa/aaa.png"],
"Loc": "XXX",
"Emp": "SSS",
"Rate": [{
"Rating": 2,
"RateID": "12345654654",
"RatedDate": new Date()
}],
"Fav": [{
"FavValue": 2,
"FavID": "1111",
"FavDate": new Date()
}]
}
Here, I want to fetch all the details by default. But from array, i need to get the object that matches the ID.
In "Rate" array it needs to match "RateID" and in "Fav" array it need to match "FavID".
Both "Rate" and "Fav" wont contains objects always.
I have tried foll mongoose aggregate:
ss.aggregate([
{ $unwind: "$Rate" },
{
$group: {
"_id": '$_id',
"Title": { "$first": "$Title" },
"Loc": { "$first": "$Loc" },
"Emp": { "$first": "$Emp" },
"Photos": { "$first": "$Photos" },
"Rate": { $max: { $cond: [ { $eq: [ "$Rate.RateID", new ObjectId(id) ] }, '$Rate.Rating', null ] } },
"Fav": { $max: { $cond : [ { $eq : [{ "$size": "$Fav" }, 0]}, null, { $cond: [ { $eq: [ "$Fav.FavID", new ObjectId(id) ] }, '$Fav.FavValue', null ] } ]} }
}
}
], function (err, AvgResult) {
res.json({"result": AvgResult});
});
For "Rate", if the array is empty it returns empty result as {}
For "Fav", it returns null always if the array is empty or if it contains object
If I send the ID as '12345654654', the result should be like
{
"Title": "AAA",
"Photos": ["/aaa/aaa.png"],
"Loc": "XXX",
"Emp": "SSS",
"Rate": 2,
"Fav": null
}
If the ID is "1111", the result should be
{
"Title": "AAA",
"Photos": ["/aaa/aaa.png"],
"Loc": "XXX",
"Emp": "SSS",
"Rate": null,
"Fav": 2
}
If "Fav" is empty array in DB like "Fav": [] and ID - is "12345654654", then the result should be as follows
{
"Title": "AAA",
"Photos": ["/aaa/aaa.png"],
"Loc": "XXX",
"Emp": "SSS",
"Rate": 2,
"Fav": null
}
can any one help to get the expected result in all the above scenario..

Resources