mongodb update value in 3 level nested array of objects - node.js

I want to update flag in array of objects which are 3 levels deep nested.
I have this array of ages:
[20, 25]
I want to set flag: 1 for those users which has type: students and ages: 20 or 25
Here is my Users collection:
{
"_id": "wef324DGSshf",
"userTypes": [
{
"type": "students",
"users": [
{
"name": "John",
"age": 20,
"flag": 0
},
{
"name": "Mike",
"age": 25,
"flag": 0
}
]
},
{
"type": "students",
"users": [
{
"name": "Henry",
"age": 40,
"flag": 0
},
{
"name": "Nick",
"age": 25,
"flag": 0
}
]
},
{
"type": "teachers",
"users": [
{
"name": "Kim",
"age": 20,
"flag": 0
},
{
"name": "Charles",
"age": 25,
"flag": 0
}
]
}
]
}
After update I expect this response:
{
"_id": "wef324DGSshf",
"userTypes": [
{
"type": "students",
"users": [
{
"name": "John",
"age": 20,
"flag": 1
},
{
"name": "Mike",
"age": 25,
"flag": 1
}
]
},
{
"type": "students",
"users": [
{
"name": "Henry",
"age": 40,
"flag": 0
},
{
"name": "Nick",
"age": 25,
"flag": 1
}
]
},
{
"type": "teachers",
"users": [
{
"name": "Kim",
"age": 20,
"flag": 0
},
{
"name": "Charles",
"age": 25,
"flag": 0
}
]
}
]
}
What I have tried so far is this query:
Users.update(
{ "userTypes.users.age": { $in: [20,25] } },
{ "$set": { "userTypes.users.$.flag": "1" } }
);
My solution is not updating the desired records, can anyone help me with the right query for this case?

Related

How to filter the response from mongoDB, so nested arrays will include only items that meet a condition?

My documents look like this
{
"_id": {
"$oid": "62825f71005ce00c5f0235c1"
},
"user": "jon",
"roles": {
"User": 2001,
},
"STOCK ": [
{
"sku": "BLACK-M",
"productname": "BLACK",
"sendout": 0,
"recived": 1,
"totalinstock": 40,
"location": "B32",
"_id": {
"$oid": "62826016005ce00c5f0235c8"
}
},
{
"sku": "CJNS",
"productname": "89796363",
"sendout": 0,
"recived": 45,
"totalinstock": 0,
"location": "B232",
"_id": {
"$oid": "62836f2d56b4f1ac79c99b8d"
}
}
],
"ORDERS": [
{
"date": {
"$date": "2022-06-02T15:23:58Z"
},
"OrderNumber": "745607",
"City": "xxxxx",
"Address": "yyyyyy",
"Phone": "8678678678",
"Name": "Holly ",
"Trackingnumber": 40,
"ZipCode": 00000,
"Province": "New ",
"Quantity": [
1
],
"Product_Name": [
" pants pants"
],
"SKU": [
"CJNS"
],
"_id": {
"$oid": "6298d61ba6eeec72b78332a7"
}
},
{
"date": {
"$date": "2022-06-02T15:23:58Z"
},
"OrderNumber": "748840",
"City": "xxxxx",
"Address": "yyyyyy",
"Phone": "354353454",
"Name": "Michael",
"Trackingnumber": 0,
"ZipCode": 00000,
"Province": "North",
"Quantity": [
1
],
"Product_Name": [
" pants pants"
],
"SKU": [
"CJNS"
],
"_id": {
"$oid": "6298d61ba6eeec72b78332a9"
}
}
]
}
I successful to return all the objects in STOCK or all the objects in ORDERS
Through this query
const foundUser= await User.find({"user":req.body.user},("Orders") ).exec()
Now I want to filter the response to include only items where "Trackingnumber" is different from 0
For the sample data I expect to receive only
{
"date": {
"$date": "2022-06-02T15:23:58Z"
},
"OrderNumber": "748840",
"City": "xxxxx",
"Address": "yyyyyy",
"Phone": "354353454",
"Name": "Michael",
"Trackingnumber": 0,
"ZipCode": 00000,
"Province": "North",
"Quantity": [
1
],
"Product_Name": [
" pants pants"
],
"SKU": [
"CJNS"
],
"_id": {
"$oid": "6298d61ba6eeec72b78332a9"
}
}
You can use an aggregation pipeline with a $filter for this:
db.collection.aggregate([
{
$match: {
"user": "jon"
}
},
{
$project: {
ORDERS: {
$filter: {
input: "$ORDERS",
as: "item",
cond: {$ne: ["$$item.Trackingnumber", 0]}
}
}
}
}
])
Playground example
User.find({"Orders" : {"Trackingnumber": 0} })

How can I mutate the json in the following way in javascript

I have been asked in an interview to mutate the array of objects in such a way that the data appears in the following manner
[
{
"companyName": "ABC",
"members": [
{
"id": 13121212,
"firstName": "Ray",
"lastName": "Fernandis",
"points": 1800,
"position": 1
},
{
"id": 13131313,
"firstName": "Carrie",
"lastName": "Yoda",
"points": 1200,
"position": 2
}
]
}]
and the sample data was given below.
[
{
"communityName": "ABC",
"lastUpdateTimestamp": {
"date": {
"year": 2020,
"month": 10,
"day": 7
},
"time": {
"hour": 18,
"minute": 6,
"second": 5,
"nano": 536529000
}
},
"data": {
"listChannelsData": [
{
"channelId": 1234,
"channelName": "BCD",
"members": [
{
"id": 13121212,
"firstName": "Ray",
"lastName": "Fernandis",
"points": 1800,
"position": 1
}
]
}
]
}
},
{
"communityName": "DEF",
"lastUpdateTimestamp": {
"date": {
"year": 2020,
"month": 10,
"day": 7
},
"time": {
"hour": 18,
"minute": 6,
"second": 21,
"nano": 47894000
}
},
"data": {
"listChannelsData": [
{
"channelId": 3421,
"channelName": "GHI",
"members": [
{
"id": 13121212,
"firstName": "Nicholas",
"lastName": "Xin",
"points": 800,
"position": 2
},
{
"id": 13131313,
"firstName": "Carrie",
"lastName": "Yoda",
"points": 1000,
"position": 1
}
]
}
]
}
}
]
The agenda for me was to print the derived json from sample json and I could only figure out this much code which was a courtesy of stackoverflow
function dictionary(data) {
var map = {};
data.forEach(item => {
if (!Array.isArray(map[item.companyName])) {
map[item.companyName] = [item.data.listChannelsData];
} else {
map[item.communityName].push(item.data.listChannelsData);
}
});
return map;
}
console.log(dictionary(data));
But now when I try to pick up the data for the member using another foreach loop, I'm not able to access the data for members. Can anyone help me with the part where I can successfully access the member array and print the company name along side it
Try this code
var newArray = []
data.map((item, index) => {
newArray[index] = {companyName : item.communityName}
newArray[index].members = item.data.listChannelsData[0].members
})
data is the given data.

Issue with to get data from MongoDB aggregate

I want data from places where userid is equal to the body.user._id
PLACE DATA
{
"_id": "5e8ddd0f7f5b174290bbefc8",
"type": 0,
"location": [
24.8757396,
67.3464698
],
"title": "E 22, Steel Town Karachi, Karachi City, Sindh, Pakistan",
"googlePlaceId": "ChIJlbvA8BIzsz4Rlh7w_fKfwus",
"createdDate": "2020-04-08T14:17:51.869Z",
"__v": 0,
},
{
"_id": "5e8de4204396310017564a2b",
"type": 0,
"location": [
24.910688,
67.0310973
],
"title": "Nazimabad, Karachi, Pakistan",
"googlePlaceId": "ChIJzZudRr0_sz4R81KZ48Ylk3Q",
"createdDate": "2020-04-08T14:48:00.557Z",
"__v": 0,
},
{
"_id": "5e8de4364396310017564a2d",
"type": 0,
"location": [
24.9180271,
67.0970916
],
"title": "Gulshan-e-Iqbal, Karachi, Pakistan",
"googlePlaceId": "ChIJsda_CLg4sz4RIghXwgIae5k",
"createdDate": "2020-04-08T14:48:22.979Z",
"__v": 0,
},
{
"_id": "5e8dea79894854524cc554e0",
"type": 0,
"location": [
24.9343322,
67.177173
],
"title": "Malir Cantt Check Post No 6, Malir Link to Super Highway, Karachi, Pakistan",
"googlePlaceId": "ChIJJ7BbsyQ4sz4RvpkV9Ig_aU4",
"createdDate": "2020-04-08T15:15:05.360Z",
"__v": 0,
}**
Visited Places DATA
{
"_id":"5e90998f8bc84d0017a6d2f3",
"visitingNo":"0",
"_userId":"5e8f3ef5434f5800170c7169"
"_placeId":"5e908fdb8bc84d0017a6d2e8"
"createdDate":"2020-04-10T16:06:39.231+00:00"
"__v":"0"
},
{
"_id":"5e90998f8bc84d0017a6d2f3",
"visitingNo":"0",
"_userId":"5e8f3ef5434f5800170c7169"
"_placeId":"5e908fdb8bc84d0017a6d2e8"
"createdDate":"2020-04-10T16:06:39.231+00:00"
"__v":"0"
},
{
"_id":"5e90998f8bc84d0017a6d2f3",
"visitingNo":"0",
"_userId":"5e8f3ef5434f5800170c7169"
"_placeId":"5e908fdb8bc84d0017a6d2e8"
"createdDate":"2020-04-10T16:06:39.231+00:00"
"__v":"0"
},
MY CODE
const palace = placeData.aggregate([
{
$lookup:{
from: `${visitplaceData}`,
// localField: "_id",
// foreignField: "_placeId",
let : {
"placeId" : "$_id"
},
pipeline : [
{ $sort: { visitingNo : -1 } },
{
$match : {
$expr : {
$and : [
{$eq: [ "$_placeId", "$$placeId" ]},
{"_userId": body.user._id}
]
}
}
},
],
as: "places"
}
}
])

How to I return a json object along with totals in mongoose?

I have a database of exercises in a workout tracker, and when I do a find(), the result is this:
[
{
"_id": "5e9dacbb6512969974bd5b2d",
"day": "2020-04-10T14:07:55.905Z",
"exercises": [
{
"type": "resistance",
"name": "Bicep Curl",
"duration": 20,
"weight": 100,
"reps": 10,
"sets": 4
}
]
},
{
"_id": "5e9dacbb6512969974bd5b2e",
"day": "2020-04-11T14:07:55.916Z",
"exercises": [
{
"type": "resistance",
"name": "Lateral Pull",
"duration": 20,
"weight": 300,
"reps": 10,
"sets": 4
}
]
},
{
"_id": "5e9dacbb6512969974bd5b2f",
"day": "2020-04-12T14:07:55.916Z",
"exercises": [
{
"type": "resistance",
"name": "Push Press",
"duration": 25,
"weight": 185,
"reps": 8,
"sets": 4
}
]
},
{
"_id": "5e9dacbb6512969974bd5b30",
"day": "2020-04-13T14:07:55.916Z",
"exercises": [
{
"type": "cardio",
"name": "Running",
"duration": 25,
"distance": 4
}
]
},
{
"_id": "5e9dacbb6512969974bd5b31",
"day": "2020-04-14T14:07:55.916Z",
"exercises": [
{
"type": "resistance",
"name": "Bench Press",
"duration": 20,
"weight": 285,
"reps": 10,
"sets": 4
}
]
},
{
"_id": "5e9dacbb6512969974bd5b32",
"day": "2020-04-15T14:07:55.916Z",
"exercises": [
{
"type": "resistance",
"name": "Bench Press",
"duration": 20,
"weight": 300,
"reps": 10,
"sets": 4
}
]
},
{
"_id": "5e9dacbb6512969974bd5b33",
"day": "2020-04-16T14:07:55.916Z",
"exercises": [
{
"type": "resistance",
"name": "Quad Press",
"duration": 30,
"weight": 300,
"reps": 10,
"sets": 4
}
]
},
{
"_id": "5e9dacbb6512969974bd5b34",
"day": "2020-04-17T14:07:55.916Z",
"exercises": [
{
"type": "resistance",
"name": "Bench Press",
"duration": 20,
"weight": 300,
"reps": 10,
"sets": 4
}
]
},
{
"_id": "5e9dacbb6512969974bd5b35",
"day": "2020-04-18T14:07:55.916Z",
"exercises": [
{
"type": "resistance",
"name": "Military Press",
"duration": 20,
"weight": 300,
"reps": 10,
"sets": 4
}
]
},
{
"_id": "5e9dacbb6512969974bd5b36",
"day": "2020-04-19T14:07:55.916Z",
"exercises": [
{
"type": "resistance",
"name": "Bench",
"duration": 30,
"distance": 2
}
]
}
]
Then I need to get total sums of statistics from each exercise, so I used mongoose aggregate to give me this data:
[
{
"_id": null,
"totalDuration": 230,
"totalWeight": 2070,
"totalSets": 32,
"totalReps": 78,
"totalDistance": 6
}
]
I want to combine these two results in one GET request, ideally doing something similar to a push where I just push the totals at the end of the first JSON object. How do I achieve this?
Something like this:
function mergeResults(resultFromFindQuery, totalSums){
var allData = {};
allData['mongoFindresult'] = resultFromFindQuery;
allData['totalSums'] = totalSums;
return allData;
}
Then use the returned value to what you need to do. Now you have both of them in the same variable.

Query to retrieve every subdocument alone without passing parent id using Mongoose

Here i like to explain my problem.
How can i write a mongoose query to retrieve every subdocument from JSON without passing parent_id.
[
{
"_id": "56a320003fe17cc7363dd0d7",
"name": "Leanna Jacobson",
"gender": "female",
"friends": [
{
"id": 0,
"name": "Riley Case"
},
{
"id": 1,
"name": "Herman Carter"
},
{
"id": 2,
"name": "Pacheco Woodard"
}
]
},
{
"_id": "56a3200001501cfa1ea2641d",
"name": "Juliana Bonner",
"gender": "female",
"friends": [
{
"id": 0,
"name": "Keller Woodward"
},
{
"id": 1,
"name": "Fern Knight"
},
{
"id": 2,
"name": "Cain Richards"
}
]
},
{
"_id": "56a3200006864c78ecb1aeed",
"name": "Gena Stark",
"gender": "female",
"friends": [
{
"id": 0,
"name": "Kate Franco"
},
{
"id": 1,
"name": "Araceli Mcclure"
},
{
"id": 2,
"name": "Molly Nelson"
}
]
},
{
"_id": "56a320006d868155161038b6",
"name": "Eve Gonzalez",
"gender": "female",
"friends": [
{
"id": 0,
"name": "Pam Lang"
},
{
"id": 1,
"name": "Christy Marks"
},
{
"id": 2,
"name": "Donovan Warren"
}
]
},
{
"_id": "56a3200066b94852f5680568",
"name": "Coleman Wooten",
"gender": "male",
"friends": [
{
"id": 0,
"name": "Roberta Olson"
},
{
"id": 1,
"name": "Roseann Reid"
},
{
"id": 2,
"name": "Kerri Russell"
}
]
}
]
Here i need to retrieve every friends details from the subdocument array friends for every parent.
so how can i write query for this?????
Suppose the name of your schema is Person, try this one.
//find all document, only select `friends` field from every document
Person.find({}, 'friends', function (err, friends) {
// the return friends is the [[friends], [friends], ...]
});

Resources