Adding Node to exisitng documents mongodb - mongodb

I am trying to update the existing document with one extra field as a new requirement in DB needs that
Existing field
[{
"_id": {
"$oid": "62a8ad644035e93c7ff24607"
},
"user_name": "demo2#devia.com",
"password": "1234",
"college_id": {
"$oid": "628dfd41ef796e8f757a5c13"
},
"basic_details": {
"first_name": "ghgh",
"middle_name": "",
"last_name": "gh",
"email": "demo2#devia.com",
"mobile_number": 1234567890
},
"address_details": {
"country": {
"country_id": {
"$oid": "623012f9683f8fb7bd213c36"
},
"country_code": "IN"
},
"state": {
"state_id": {
"$oid": "623013d9683f8fb7bd2381c4"
},
"state_code": "MP"
},
"city": {
"city_id": {
"$oid": "6230139f683f8fb7bd21f1a9"
},
"city_name": "Akodia"
},
"address_line1": "",
"address_line2": "",
"pincode": ""
},
"is_verify": false,
"last_accessed": {
"$date": {
"$numberLong": "1655221604144"
}
},
"created_at": {
"$date": {
"$numberLong": "1655221604144"
}
},
"course_details": {}
}]
Needs to update all fields
[{
"_id": {
"$oid": "62bf2cf2a8c782741bbcc398"
},
"user_name": "a#exaple.com",
"password": "$2b$12$NgLNYm5jUBmFUq.w15.qCO35GiTJX09jAnOpoGuPt9G7GNuOkVN7K",
"college_id": {
"$oid": "628dfd41ef796e8f757a5c13"
},
"basic_details": {
"email": "a#example.com",
"mobile_number": "9898989898",
"first_name": "Fahim",
"middle_name": "",
"last_name": "Ashhab",
"nationality": "Antiguans",
"date_of_birth": "2003-02-04",
"admission_year": "2022-23",
"gender": "Male",
"category": "General",
"para_ability": {
"is_disable": false,
"name_of_disability": ""
}
},
"address_details": {
"communication_address": {
"country": {
"country_id": {
"$oid": "623012f9683f8fb7bd213c36"
},
"country_code": "IN"
},
"state": {
"state_id": {
"$oid": "623013d9683f8fb7bd2380ef"
},
"state_code": "AP"
},
"city": {
"city_id": {
"$oid": "6230139f683f8fb7bd21ebc8"
},
"city_name": "Akasahebpet"
},
"address_line1": "jjkjk",
"address_line2": "uiui",
"pincode": "989898"
}
},
"is_verify": true,
"last_accessed": {
"$date": {
"$numberLong": "1656696050670"
}
},
"created_at": {
"$date": {
"$numberLong": "1656696050670"
}
},
"allocate_to_counselor": {
"counselor_id": {
"$oid": "62bfd13a5ce8a398ad101bd7"
},
"counselor_name": "test",
"last_update": {
"$date": {
"$numberLong": "1656817948401"
}
}
},
"course_details": {
"BSc": {
"course_id": {
"$oid": "628e03d94e22276b98231407"
},
"course_name": "BSc",
"application_id": {
"$oid": "62bf2cf2a8c782741bbcc399"
},
"status": "Incomplete",
"specs": [
{
"spec_name": "Physician Assistant",
"is_activated": true
}
]
}
}
}]
Query Tried nothing is happening
db.collection.aggregate([
{$match:{"address_details.country": {$exists:true}}},
{$set:{address_details:{communication_address:"$address_details"}}}
])
2nd Query Tried didn't go through
db.studentsPrimaryDetails.updateMany({
"address_details.communication_address": {"$exist":false}},
{$set: {"address_details.communication_address":"$address_details"}})
The desired result needs to be
from this
"address_details": {
"country": {
"country_id": {
"$oid": "623012f9683f8fb7bd213c36"
},
"country_code": "IN"
},
"state": {
"state_id": {
"$oid": "623013d9683f8fb7bd2381c4"
},
"state_code": "MP"
},
"city": {
"city_id": {
"$oid": "6230139f683f8fb7bd21f1a9"
},
"city_name": "Akodia"
},
"address_line1": "",
"address_line2": "",
"pincode": ""
}
to this
"address_details": {
"communication_address": {
"country": {
"country_id": {
"$oid": "623012f9683f8fb7bd213c36"
},
"country_code": "IN"
},
"state": {
"state_id": {
"$oid": "623013d9683f8fb7bd2380ef"
},
"state_code": "AP"
},
"city": {
"city_id": {
"$oid": "6230139f683f8fb7bd21ebc8"
},
"city_name": "Akasahebpet"
},
"address_line1": "jjkjk",
"address_line2": "uiui",
"pincode": "989898"
}
}
Don't know what I am doing wrong.
Edit :
Desired full output
[{
"_id": {
"$oid": "62bf2cf2a8c782741bbcc398"
},
"user_name": "a#example.com",
"password": "12345678",
"college_id": {
"$oid": "628dfd41ef796e8f757a5c13"
},
"basic_details": {
"email": "a#example.com",
"mobile_number": "9898989898",
"first_name": "Fahim",
"middle_name": "",
"last_name": "Ashhab",
"nationality": "Antiguans",
"date_of_birth": "2003-02-04",
"admission_year": "2022-23",
"gender": "Male",
"category": "General",
"para_ability": {
"is_disable": false,
"name_of_disability": ""
}
},
"address_details": {
"communication_address": {
"country": {
"country_id": {
"$oid": "623012f9683f8fb7bd213c36"
},
"country_code": "IN"
},
"state": {
"state_id": {
"$oid": "623013d9683f8fb7bd2380ef"
},
"state_code": "AP"
},
"city": {
"city_id": {
"$oid": "6230139f683f8fb7bd21ebc8"
},
"city_name": "Akasahebpet"
},
"address_line1": "jjkjk",
"address_line2": "uiui",
"pincode": "989898"
}
},
"is_verify": true,
"last_accessed": {
"$date": {
"$numberLong": "1656696050670"
}
},
"created_at": {
"$date": {
"$numberLong": "1656696050670"
}
},
"allocate_to_counselor": {
"counselor_id": {
"$oid": "62bfd13a5ce8a398ad101bd7"
},
"counselor_name": "viru chaudhary",
"last_update": {
"$date": {
"$numberLong": "1656817948401"
}
}
},
"course_details": {
"BSc": {
"course_id": {
"$oid": "628e03d94e22276b98231407"
},
"course_name": "BSc",
"application_id": {
"$oid": "62bf2cf2a8c782741bbcc399"
},
"status": "Incomplete",
"specs": [
{
"spec_name": "Physician Assistant",
"is_activated": true
}
]
}
}
}]```

One option is:
Use $exists instead of $exist
Use pipeline in order to be able to $set the value from another fields' value
db.collection.updateMany(
{"address_details.communication_address": {$exists: false}},
[{$set: {address_detailsB: {communication_address: "$address_details"}}},
{$set: {
address_details: "$address_detailsB",
address_detailsB: "$$REMOVE"}
}
])
See how it works on the playground example
The aggregation query that you first tried, does not not update the db, it only returns data. In order to use it as an updater you need to add a $merge step.

Related

mongodb join array of result to single document

i have used this schema
conversation_id: 12345,
time: time,
members: ['user1', 'user2'],
messages: [
{
sender: 'user1',
message: 'Hello World',
timestamp: time
},
{
sender: 'user1',
message: 'Hello World',
timestamp: time
}],
total_messages: 2
}
but i need to know how to get all the results by sorted
db.chats.aggregate(
{
/**
* query: The query in MQL.
*/
$match: {
"members": {
"$all": [
ObjectId('63ad8631e0d6cfe452b80677'),
ObjectId('63adadf287e482e6f128ec0e'),
]
}
},
},
{
/**
* Provide any number of field/order pairs.
*/
$sort: {
"created_at": -1
}
},
{
/**
* specifications: The fields to
* include or exclude.
*/
$project: {
"_id": 0,
// "members": 1,
"result": {
$sortArray: {input: "$message", sortBy: {created_at: -1}}
}
}
},
)
I have used this.. but thing is every things are in result block and I want it to in one array so I can fetch previous messages with $limit and $skip so I can send back to API of user message..
here is my sample data
[
{
"result": [
{
"uuid": "df359053-5b69-4fc3-ac42-57aaf70ec9d9",
"sender": {
"$oid": "63ad8631e0d6cfe452b80677"
},
"message": "00011",
"created_at": {
"$date": "2023-01-10T19:52:26Z"
}
},
{
"uuid": "0cfe04ab-ccf2-4eb9-8760-d3471f033ea6",
"sender": {
"$oid": "63ad8631e0d6cfe452b80677"
},
"message": "00010",
"created_at": {
"$date": "2023-01-10T19:52:15Z"
}
}
]
},
{
"result": [
{
"uuid": "fe54bf97-5dad-4d3f-ada8-ea1f1ab31039",
"sender": {
"$oid": "63ad8631e0d6cfe452b80677"
},
"message": "00010",
"created_at": {
"$date": "2023-01-10T19:52:14Z"
}
},
{
"uuid": "9face81d-b989-4662-a090-2f8f498b1a7b",
"sender": {
"$oid": "63ad8631e0d6cfe452b80677"
},
"message": "00010",
"created_at": {
"$date": "2023-01-10T19:52:12Z"
}
},
{
"uuid": "8578ce16-f3ac-4ceb-b779-0c1f3e8fec2f",
"sender": {
"$oid": "63ad8631e0d6cfe452b80677"
},
"message": "00010",
"created_at": {
"$date": "2023-01-10T19:51:02Z"
}
}
]
},
{
"result": [
{
"uuid": "ef6f12e0-b601-4377-8ff9-28921799985b",
"sender": {
"$oid": "63ad8631e0d6cfe452b80677"
},
"message": "00009",
"created_at": {
"$date": "2023-01-10T19:51:00Z"
}
},
{
"uuid": "6fcbcc3b-ff09-4e1c-9ce5-d73790911592",
"sender": {
"$oid": "63ad8631e0d6cfe452b80677"
},
"message": "00008",
"created_at": {
"$date": "2023-01-10T19:50:47Z"
}
},
{
"uuid": "fdde26cd-6688-466a-be61-37ac8e312a70",
"sender": {
"$oid": "63ad8631e0d6cfe452b80677"
},
"message": "00007",
"created_at": {
"$date": "2023-01-10T19:49:33Z"
}
}
]
},
{
"result": [
{
"uuid": "fdde26cd-6688-466a-be61-37ac8e312a70",
"sender": {
"$oid": "63ad8631e0d6cfe452b80677"
},
"message": "00007",
"created_at": {
"$date": "2023-01-10T19:49:33Z"
}
},
{
"uuid": "fb72bef2-ceff-4e22-80cd-b54da6ba6f01",
"sender": {
"$oid": "63ad8631e0d6cfe452b80677"
},
"message": "00006",
"created_at": {
"$date": "2023-01-10T19:48:51Z"
}
},
{
"uuid": "3ffee1e6-8eb4-4a93-99a2-329576dc7754",
"sender": {
"$oid": "63ad8631e0d6cfe452b80677"
},
"message": "00005",
"created_at": {
"$date": "2023-01-10T19:48:34Z"
}
},
{
"uuid": "927726bd-acc9-461b-98db-9ce07cca5ff0",
"sender": {
"$oid": "63ad8631e0d6cfe452b80677"
},
"message": "00004",
"created_at": {
"$date": "2023-01-10T19:48:31Z"
}
}
]
},
{
"result": [
{
"uuid": "927726bd-acc9-461b-98db-9ce07cca5ff0",
"sender": {
"$oid": "63ad8631e0d6cfe452b80677"
},
"message": "00004",
"created_at": {
"$date": "2023-01-10T19:48:31Z"
}
},
{
"uuid": "664cb8fb-0284-4ad2-af1f-d9458fb09c24",
"sender": {
"$oid": "63ad8631e0d6cfe452b80677"
},
"message": "00003",
"created_at": {
"$date": "2023-01-10T19:48:25Z"
}
},
{
"uuid": "460e8a5a-327f-47c9-a8c3-76772cca4cc7",
"sender": {
"$oid": "63ad8631e0d6cfe452b80677"
},
"message": "00002",
"created_at": {
"$date": "2023-01-10T19:22:03Z"
}
},
{
"uuid": "ed4e5060-45f9-4f4a-a6a0-e45eddbd64bc",
"sender": {
"$oid": "63ad8631e0d6cfe452b80677"
},
"message": "00002",
"created_at": {
"$date": "2023-01-10T19:22:03Z"
}
}
]
},
{
"result": [
{
"uuid": "a45e6738-afb4-47aa-a8f4-fdf1d70eeb5f",
"sender": {
"$oid": "63ad8631e0d6cfe452b80677"
},
"message": "00002",
"created_at": {
"$date": "2023-01-10T19:22:03Z"
}
},
{
"uuid": "466b8569-12c4-4d06-8572-eb5999f0e4ae",
"sender": {
"$oid": "63ad8631e0d6cfe452b80677"
},
"message": "00002",
"created_at": {
"$date": "2023-01-10T19:22:03Z"
}
},
{
"uuid": "314b60eb-1eaf-4a72-a7a6-528ab474a0d9",
"sender": {
"$oid": "63ad8631e0d6cfe452b80677"
},
"message": "00002",
"created_at": {
"$date": "2023-01-10T19:22:03Z"
}
},
{
"uuid": "460e8a5a-327f-47c9-a8c3-76772cca4cc7",
"sender": {
"$oid": "63ad8631e0d6cfe452b80677"
},
"message": "00002",
"created_at": {
"$date": "2023-01-10T19:22:03Z"
}
}
]
},
{
"result": [
{
"uuid": "a45e6738-afb4-47aa-a8f4-fdf1d70eeb5f",
"sender": {
"$oid": "63ad8631e0d6cfe452b80677"
},
"message": "00002",
"created_at": {
"$date": "2023-01-10T19:22:03Z"
}
},
{
"uuid": "4f56f58d-1b0c-48f9-b3b6-c63020068760",
"sender": {
"$oid": "63ad8631e0d6cfe452b80677"
},
"message": "00002",
"created_at": {
"$date": "2023-01-10T19:21:55Z"
}
},
{
"uuid": "4fb86042-93ef-4209-88ca-8c287f16a2f6",
"sender": {
"$oid": "63ad8631e0d6cfe452b80677"
},
"message": "00001",
"created_at": {
"$date": "2023-01-10T19:20:30Z"
}
},
{
"uuid": "3a6dc43d-bdb5-41b9-be93-15ab389380a9",
"sender": {
"$oid": "63ad8631e0d6cfe452b80677"
},
"message": "New Docu ",
"created_at": {
"$date": "2023-01-10T18:44:01Z"
}
}
]
},
{
"result": [
{
"uuid": "69b1dd00-8ecf-4ba3-8df4-2cbba3887505",
"sender": {
"$oid": "63adadf287e482e6f128ec0e"
},
"message": "88888888888888888888",
"created_at": {
"$date": "2023-01-10T16:01:22Z"
}
},
{
"uuid": "3ea03321-3c99-48b6-a7fd-2cc5fa514fb3",
"sender": {
"$oid": "63ad8631e0d6cfe452b80677"
},
"message": "0000000000000",
"created_at": {
"$date": "2023-01-10T15:51:20Z"
}
},
{
"uuid": "c8e35012-1106-4e3f-b678-6040002d54b8",
"sender": {
"$oid": "63ad8631e0d6cfe452b80677"
},
"message": "pppppp",
"created_at": {
"$date": "2023-01-10T15:40:24Z"
}
}
]
},
{
"result": [
{
"uuid": "b78f1288-5363-4b0f-9bbe-ddf73f60fac1",
"sender": {
"$oid": "63ad8631e0d6cfe452b80677"
},
"message": "Kio nn sass,,,",
"created_at": {
"$date": "2023-01-10T18:46:39Z"
}
},
{
"uuid": "94e3ae3a-eb2c-4ceb-b580-e97f4ec49aba",
"sender": {
"$oid": "63ad8631e0d6cfe452b80677"
},
"message": "Kio nn sass,,,",
"created_at": {
"$date": "2023-01-10T18:44:57Z"
}
},
{
"uuid": "80c86174-9836-477b-b0d3-e4cb968b015a",
"sender": {
"$oid": "63ad8631e0d6cfe452b80677"
},
"message": "Another messgee 2",
"created_at": {
"$date": "2023-01-10T18:44:45Z"
}
},
{
"uuid": "3a6dc43d-bdb5-41b9-be93-15ab389380a9",
"sender": {
"$oid": "63ad8631e0d6cfe452b80677"
},
"message": "New Docu ",
"created_at": {
"$date": "2023-01-10T18:44:01Z"
}
},
{
"uuid": "69b1dd00-8ecf-4ba3-8df4-2cbba3887505",
"sender": {
"$oid": "63adadf287e482e6f128ec0e"
},
"message": "i am fine thanks",
"created_at": {
"$date": "2023-01-10T16:01:22Z"
}
},
{
"uuid": "3ea03321-3c99-48b6-a7fd-2cc5fa514fb3",
"sender": {
"$oid": "63ad8631e0d6cfe452b80677"
},
"message": "Buddy hhh.. ",
"created_at": {
"$date": "2023-01-10T15:51:20Z"
}
},
{
"uuid": "c8e35012-1106-4e3f-b678-6040002d54b8",
"sender": {
"$oid": "63ad8631e0d6cfe452b80677"
},
"message": "LOL How are you ",
"created_at": {
"$date": "2023-01-10T15:36:24Z"
}
}
]
}
]
I have made 3 messages collection document after 3 new document is created.. i will make it 1000 in production..
and I have use another thing called $concatArray but its adding only fields which I explicitly give example
// MongoDB Playground
// Use Ctrl+Space inside a snippet or a string literal to trigger completions.
const database = 'test3';
// The current database to use.
use(database);
// db.chats.find({
// "members": {
// "$eq": [
// ObjectId('63ad8631e0d6cfe452b80677'),
// ObjectId('63adadf287e482e6f128ec0e')
// ]
// }
// }
// )
// db.chats.aggregate(
// {
// $match: {
// "members": {
// "$all": [
// ObjectId('63ad8631e0d6cfe452b80677'),
// // ObjectId('63adadf287e482e6f128ec0e'),
// ObjectId('63b3c2b8ce51cf1fca0325ad')
// ]
// },
// }
// },
// {
// $sort: {
// "created_at": -1
// }
// },
// // {
// // $project: {
// // "total": 1,
// // "_id": 0
// // }
// // },
// {
// $limit: 1
// },
// )
// .sort({"created_at": -1})
// db.chats.find(
// {
// "members": {
// "$all": [
// ObjectId('63ad8631e0d6cfe452b80677'),
// ObjectId('63adadf287e482e6f128ec0e'),
// // ObjectId('63b3c2b8ce51cf1fca0325ad')
// ]
// }
// },
// )
// db.chats.find({
// "members": {
// "$eq": [
// ObjectId('63ad8631e0d6cfe452b80677'),
// ObjectId('63adadf287e482e6f128ec0e')
// ]
// }
// }
// )
db.chats.aggregate(
{
/**
* query: The query in MQL.
*/
$match: {
"members": {
"$all": [
ObjectId('63ad8631e0d6cfe452b80677'),
ObjectId('63adadf287e482e6f128ec0e'),
]
}
},
},
{
/**
* Provide any number of field/order pairs.
*/
$sort: {
"created_at": -1
}
},
{
/**
* specifications: The fields to
* include or exclude.
*/
$project: {
"_id": 0,
// "members": 1,
"result": {
$sortArray: {input: "$message", sortBy: {created_at: -1}},
}
}
},
{
/**
* specifications: The fields to
* include or exclude.
*/
$project: {
"messages": {
'$concatArrays': [
"$result", "$result"
]
}
}
}
)
it will add two result to messages but not to all of that result
here my demo MongoDB collections https://pastebin.com/mt4i3HXr

MongoDb extract array

I have a mongodb which I want to extract some specific data.
Here is my json:
{
"jobs" : [
{
"id": 554523,
"code": "1256-554523",
"name": "Banco de Talentos",
"status": "published",
"type": "vacancy_type_effective",
"publicationType": "external",
"numVacancies": 1,
"departmentId": 108141,
"departmentName": "FUTURAS OPORTUNIDADES",
"roleId": 169970,
"roleName": "BANCO DE TALENTOS",
"createdAt": "2020-10-30T12:23:48.572Z",
"updatedAt": "2020-12-30T23:21:30.403Z",
"branchId": null,
"branchName": null
},
{
"id": 616834,
"code": "1256-616834",
"name": "YYYYYY (o) YYYYY",
"status": "frozen",
"type": "vacancy_type_effective",
"publicationType": "external",
"numVacancies": 1,
"departmentId": 109190,
"departmentName": "TESTE TESTE",
"roleId": 165712,
"roleName": "SL - TESTE PL",
"createdAt": "2020-12-16T14:17:36.187Z",
"updatedAt": "2021-01-29T17:08:43.613Z",
"branchId": 120448,
"branchName": "TESTE TESTE1"
}
],
"application": [
{
"id": 50707344,
"score": 40.251965332031254,
"partnerName": "indeed",
"endedAt": null,
"createdAt": "2020-12-21T11:21:30.587Z",
"updatedAt": "2021-02-18T22:02:35.866Z",
"tags": {},
"candidate": {
"birthdate": "1986-04-04",
"id": 578615,
"name": "TESTE",
"lastName": "TESTE TESTE",
"email": "teste#teste.com.br",
"identificationDocument": "34356792807",
"countryOfOrigin": "BR",
"linkedinProfileUrl": "teste",
"gender": "female",
"mobileNumber": "+5511972319799",
"phoneNumber": "(11)2463-2039"
},
"job": {
"id": 619713,
"name": "XXXXde XXXX Pleno"
},
"manualCandidate": null,
"currentStep": {
"id": 3527370,
"name": "Cadastro",
"status": "done"
}
},
{
"id": 50707915,
"score": 3.75547943115234E+1,
"partnerName": "indeed",
"endedAt": null,
"createdAt": "2020-12-21T11:31:31.877Z",
"updatedAt": "2021-02-18T14:07:06.605Z",
"tags": {},
"candidate": {
"birthdate": "1971-10-02",
"id": 919358,
"name": "TESTE TESTE",
"lastName": "SILVA",
"email": "teste.teste#teste.com",
"identificationDocument": "3232323232",
"countryOfOrigin": "BR",
"linkedinProfileUrl": "teste/",
"gender": "female",
"mobileNumber": "11 94021- 5521",
"phoneNumber": "+5511995685247"
},
"job": {
"id": 619713,
"name": "Analista de XXXXX Pleno"
},
"manualCandidate": null,
"currentStep": {
"id": 3527370,
"name": "Cadastro",
"status": "done"
}
}
]
}
My question is: How can I extract only the array objects in jobs and application separately? Anyone knows the code in Mongodb for do this?
I need do this task for after I can insert the extract separated data in different collections.
Thanks a lot.
Unfortunately there is no real "good" way of doing this. Here is an example of how I would do it by using $facet and other operators to manipulate the structure
db.collection.aggregate([
{
$match: {
/** your query*/
}
},
{
$facet: {
jobs: [
{
$unwind: "$jobs"
},
{
$replaceRoot: {
newRoot: "$jobs"
}
}
],
applications: [
{
$unwind: "$application"
},
{
$replaceRoot: {
newRoot: "$application"
}
}
]
}
},
{
$addFields: {
"merged": {
"$concatArrays": [
"$jobs",
"$applications"
]
}
}
},
{
$unwind: "$merged"
},
{
"$replaceRoot": {
"newRoot": "$merged"
}
}
])
Mongo Playground
I would personally just do it in code after you fetched the document.

mongodb aggregate lookup with a query

I have collections with following values:
reports
{
"_id": { "$oid": "5f05e1d13e0f6637739e215b" },
"testReport": [
{
"name": "Calcium",
"value": "87",
"slug": "ca",
"details": {
"description": "description....",
"recommendation": "recommendation....",
"isNormal": false
}
},
{
"name": "Magnesium",
"value": "-98",
"slug": "mg",
"details": {
"description": "description....",
"recommendation": "recommendation....",
"isNormal": false
}
}
],
"patientName": "Patient Name",
"clinicName": "Clinic",
"gender": "Male",
"bloodGroup": "A",
"createdAt": { "$date": "2020-07-08T15:10:09.612Z" },
"updatedAt": { "$date": "2020-07-08T15:10:09.612Z" }
},
setups
{
"_id": { "$oid": "5efcba7503f4693d164e651d" },
"code": "Ca",
"codeLower": "ca",
"name": "Calcium",
"valueFrom": -75,
"valueTo": -51,
"treatmentDescription": "description...",
"isNormal": false,
"gender": "",
"recommendation": "recommendation...",
"createdAt": { "$date": "2020-07-01T16:31:50.205Z" },
"updatedAt": { "$date": "2020-07-01T16:31:50.205Z" }
},
{
"_id": { "$oid": "5efcba7503f4693d164e651e" }, // <=== should find this for Calcium
"code": "Ca",
"codeLower": "ca",
"name": "Calcium",
"valueFrom": 76,
"valueTo": 100,
"treatmentDescription": "description...",
"isNormal": false,
"gender": "",
"recommendation": "recommendation...",
"createdAt": { "$date": "2020-07-01T16:31:50.205Z" },
"updatedAt": { "$date": "2020-07-01T16:31:50.205Z" }
},
{
"_id": { "$oid": "5efcba7603f4693d164e65bb" }, // <=== should find this for Magnesium
"code": "Mg",
"codeLower": "mg",
"name": "Magnesium",
"valueFrom": -100,
"valueTo": -76,
"treatmentDescription": "description...",
"isNormal": false,
"gender": "",
"recommendation": "recommendation...",
"createdAt": { "$date": "2020-07-01T16:31:50.205Z" },
"updatedAt": { "$date": "2020-07-01T16:31:50.205Z" }
},
{
"_id": { "$oid": "5efcba7503f4693d164e6550" },
"code": "Mg",
"codeLower": "mg",
"name": "Magnesium",
"valueFrom": 76,
"valueTo": 100,
"treatmentDescription": "description...",
"isNormal": false,
"gender": "",
"recommendation": "recommendation...",
"createdAt": { "$date": "2020-07-01T16:31:50.205Z" },
"updatedAt": { "$date": "2020-07-01T16:31:50.205Z" }
}
I want to search the value from reports collection and check whether the value is in range from the setups collection and return the _id and add the returned _ids in setupIds field on reports collection.
I tried with the following aggregation framework:
db.reports.aggegrate([
{
'$match': {
'_id': new ObjectId('5f05e1d13e0f6637739e215b')
}
}, {
'$lookup': {
'from': 'setups',
'let': {
'testValue': '$testReport.value',
'testName': '$testReport.name'
},
'pipeline': [
{
'$match': {
'$expr': {
{
'$and': [
{
'$eq': [
'$name', '$$testName'
]
}, {
'$gte': [
'$valueTo', '$$testValue'
]
}, {
'$lte': [
'$valueFrom', '$$testValue'
]
}
]
}
}
}
}
],
'as': 'setupIds'
}
}
])
This query didn't find the expected results.
This is the updated reports collection I want:
{
"_id": { "$oid": "5f05e1d13e0f6637739e215b" },
"setupIds": [{ "$oid": "5efcba7503f4693d164e651e" }, { "$oid": "5efcba7603f4693d164e65bb" }], // <=== Here, array of the ObjectId (ref: "Setups")
"patientName": "Patient Name",
"clinicName": "Clinic",
"gender": "Male",
"bloodGroup": "A",
"createdAt": { "$date": "2020-07-08T15:10:09.612Z" },
"updatedAt": { "$date": "2020-07-08T15:10:09.612Z" }
},
You can try like following
[{
$match: {
_id: ObjectId('5f05e1d13e0f6637739e215b')
}
}, {
$unwind: {
path: "$testReport"
}
}, {
$lookup: {
from: 'setup',
'let': {
testValue: {
$toInt: '$testReport.value'
},
testName: '$testReport.name'
},
pipeline: [{
$match: {
$expr: {
$and: [{
"$eq": [
"$name",
"$$testName"
]
},
{
"$gte": [
"$valueTo",
"$$testValue"
]
},
{
"$lte": [
"$valueFrom",
"$$testValue"
]
}
]
}
}
}],
as: 'setupIds'
}
}, {
$group: {
_id: "$_id",
patientName: {
$first: "$patientName"
},
clinicName: {
$first: "$clinicName"
},
gender: {
$first: "$gender"
},
bloodGroup: {
$first: "$bloodGroup"
},
createdAt: {
$first: "$createdAt"
},
updatedAt: {
$first: "$updatedAt"
},
setupIds: {
$addToSet: "$setupIds._id"
}
}
}, {
$addFields: {
setupIds: {
$reduce: {
input: "$setupIds",
initialValue: [],
in: {
$setUnion: ["$$this", "$$value"]
}
}
}
}
}]
Working Mongo playground

How to get ids of parents based on deeply nested sub document?

This question is in continuation with older question: Parent.save() not working when sub document / deeply nested document is modified
Say I have a document as below :
{
"apiCallCount": 1,
"_id": "5e0da052b4b3fe5188602e11",
"email": "abc#def.net",
"password": "123123",
"userName": "username",
"companyName": "companyName",
"apiKey": "apiKey",
"solutionType": "solutionType",
"parentCompany": "parentCompany",
"buildings": [
{
"gateways": [
{
"devices": [
{
"_id": "5e0da052b4b3fe5188602e15",
"serialNumber": "serialNumber 1",
"area": "area",
"connectionStatus": 0,
"gatewayKey": "gatewayKey",
"applicationNumber": 11,
"firmwareVersion": "firmwareVersion",
"needsAttention": true,
"verificationCode": "123456",
"patientRiskStatus": "patientRiskStatus",
"patientFirstName": "UPDATED!!!",
"patientLastName": "patientLastName",
"createdAt": "2020-01-02T07:48:34.287Z",
"updatedAt": "2020-01-02T07:48:34.287Z"
},
{
"_id": "5e0da052b4b3fe5188602e14",
"serialNumber": "serialNumber 2",
"area": "area",
"connectionStatus": 0,
"gatewayKey": "gatewayKey",
"applicationNumber": 22,
"firmwareVersion": "firmwareVersion",
"needsAttention": true,
"verificationCode": "987654",
"patientRiskStatus": "patientRiskStatus",
"patientFirstName": "patientFirstName",
"patientLastName": "patientLastName",
"createdAt": "2020-01-02T07:48:34.288Z",
"updatedAt": "2020-01-02T07:48:34.288Z"
}
],
"_id": "5e0da052b4b3fe5188602e13",
"gatewayName": "gatewayName 1",
"gatewayKey": "gatewayKey",
"suite": "suite",
"createdAt": "2020-01-02T07:48:34.288Z",
"updatedAt": "2020-01-02T07:48:34.288Z"
}
],
"_id": "5e0da052b4b3fe5188602e12",
"buildingName": "buildingName 1",
"address": "address",
"suite": "suite",
"floor": "floor",
"timeZone": "String",
"createdAt": "2020-01-02T07:48:34.288Z",
"updatedAt": "2020-01-02T07:48:34.288Z"
}
],
"createdAt": "2020-01-02T07:48:34.289Z",
"updatedAt": "2020-01-02T09:10:25.200Z",
"__v": 0
}
I am able to dig through document and able to get device sub document with "verificationCode": "123456"
Now I want to get gatewayID(one level up) and buildingID(two level up) for this device.
Currently I have a call like this :
I am trying to update parent doc based on deeply nested sub-document.
I get sub document by accountId and verification code like below.
and then need to update the parent.
In my sample below I Put hard-coded ids which i need to get run time.
if (newlySavedUser) {
try {
let result = await Account.findByIdAndUpdate(
accountId,
{
$set: {
"buildings.$[building].gateways.$[gateway].devices.$[device].patientFirstName": "userName",
"buildings.$[building].gateways.$[gateway].devices.$[device].patientLastName": "userName1"
}
},
{
arrayFilters: [
{ "building._id": ObjectId("5d254bb179584ebcbb68b712") }, /// <---- I want to get this buildingId
{ "gateway._id": ObjectId("5d254b64ba574040d9632ada") }, /// <---- I want to get this gatewayId
{ "device.verificationCode": "4144" } /// <-- based on this verificationCode
],
new: true
}
);
if (!result) return res.status(404);
console.log(result)
//res.send(result);
} catch (err) {
console.log(err);
res.status(500).send("Something went wrong");
}
}
Trying "tom slabbaert" solution for aggregate.
Account.aggregate([
{
$unwind: "$buildings"
},
{
$unwind: "$gateways"
},
{
$match: {
"buildings.gateways.devices.verificationCode": "4144"
}
},
{
$project: {
buildingID: "$buildings._id",
gatewayID: "$gateways._id",
}
}
]).exec((err, result)=>{
console.log("result", result)
if(err) throw err;
});
Your help is appreciated.
You can use this 3 level $unwind aggregation, and then match the document you want:
db.collection.aggregate([
{
$unwind: "$buildings"
},
{
$unwind: "$buildings.gateways"
},
{
$unwind: "$buildings.gateways.devices"
},
{
$match: {
"buildings._id": "5e0da052b4b3fe5188602e12",
"buildings.gateways._id": "5e0da052b4b3fe5188602e13",
"buildings.gateways.devices.verificationCode": "123456"
}
}
])
This will give you the following result:
[
{
"__v": 0,
"_id": "5e0da052b4b3fe5188602e11",
"apiCallCount": 1,
"apiKey": "apiKey",
"buildings": {
"_id": "5e0da052b4b3fe5188602e12",
"address": "address",
"buildingName": "buildingName 1",
"createdAt": "2020-01-02T07:48:34.288Z",
"floor": "floor",
"gateways": {
"_id": "5e0da052b4b3fe5188602e13",
"createdAt": "2020-01-02T07:48:34.288Z",
"devices": {
"_id": "5e0da052b4b3fe5188602e15",
"applicationNumber": 11,
"area": "area",
"connectionStatus": 0,
"createdAt": "2020-01-02T07:48:34.287Z",
"firmwareVersion": "firmwareVersion",
"gatewayKey": "gatewayKey",
"needsAttention": true,
"patientFirstName": "UPDATED!!!",
"patientLastName": "patientLastName",
"patientRiskStatus": "patientRiskStatus",
"serialNumber": "serialNumber 1",
"updatedAt": "2020-01-02T07:48:34.287Z",
"verificationCode": "123456"
},
"gatewayKey": "gatewayKey",
"gatewayName": "gatewayName 1",
"suite": "suite",
"updatedAt": "2020-01-02T07:48:34.288Z"
},
"suite": "suite",
"timeZone": "String",
"updatedAt": "2020-01-02T07:48:34.288Z"
},
"companyName": "companyName",
"createdAt": "2020-01-02T07:48:34.289Z",
"email": "abc#def.net",
"parentCompany": "parentCompany",
"password": "123123",
"solutionType": "solutionType",
"updatedAt": "2020-01-02T09:10:25.200Z",
"userName": "username"
}
]
Mongoplayground
A simple aggregation would suffice:
db.collection.aggregate([
{
$unwind: "$buildings"
},
{
$unwind: "$buildings.gateways"
},
{
$match: {
"buildings.
gateways.devices.verificationCode": "123456"
}
},
{
$project: {
buildingID: "$buildings._id",
gatewayID: "$gateways._id",
}
}
])
If its possible to get duplicates you can $group on buildingID to avoid that.

Filter nested array in mongodb? [duplicate]

This question already has answers here:
Find in Double Nested Array MongoDB
(2 answers)
Closed 4 years ago.
I have a document that looks like so:
{
"_id": {
"$oid": "5b1586ccf0c56353e89d330b"
},
"address": {
"street": "123 Street",
"address2": "Address 2",
"city": "Some City",
"state": "MI",
"zip": "12345"
},
"subs": [
{
"invoices": [
{
"address": {
"street": "3061 Pine Ave SW",
"city": "Grandville",
"state": "AK",
"zip": "49418"
},
"lineItem": [
{
"images": [
{
"_id": {
"$oid": "5b1fca54e6ee1d80c463612d"
},
"name": "1528810066348_RSA Logo.jpeg",
"url": "https....",
"uploadDate": {
"$date": "2018-06-12T13:27:46.931Z"
},
"size": 91819
}
],
"_id": {
"$oid": "5b1fca54e6ee1d80c463612c"
},
"desc": "2",
"amt": 2
}
],
"_id": {
"$oid": "5b1fca54e6ee1d80c463612b"
}
}
],
"_id": {
"$oid": "5b1fc7f23b595481d4599f58"
},
"email": "a#a.com",
"scope": "Roof",
},
{
"invoices": [
{
"address": {
"street": "3061 Pine Ave SW",
"city": "Grandville",
"state": "AL",
"zip": "49418"
},
"lineItem": [
{
"images": [
{
"_id": {
"$oid": "5b1fca2fe6ee1d80c463612a"
},
"name": "1528810029700_RSA Stamp.png",
"url": "https....",
"uploadDate": {
"$date": "2018-06-12T13:27:10.403Z"
},
"size": 238113
}
],
"_id": {
"$oid": "5b1fca2fe6ee1d80c4636129"
},
"desc": "1",
"amt": 1
}
],
"_id": {
"$oid": "5b1fca2fe6ee1d80c4636128"
}
},
{
"address": {
"street": "3061 Pine Ave SW",
"city": "Grandville",
"state": "AL",
"zip": "49418"
},
"lineItem": [
{
"images": [
{
"_id": {
"$oid": "5b1fd05b0d1f7185e02e9c40"
},
"name": "1528811607099_error page.PNG",
"url": "https....",
"uploadDate": {
"$date": "2018-06-12T13:53:28.080Z"
},
"size": 224772
}
],
"_id": {
"$oid": "5b1fd05b0d1f7185e02e9c3f"
},
"desc": "3",
"amt": 3
}
],
"_id": {
"$oid": "5b1fd05b0d1f7185e02e9c3e"
}
}
],
"_id": {
"$oid": "5b1fc7f23b595481d4599f55"
},
"email": "b#b.com",
"scope": "Siding",
}
],
"firstName": "",
"lastName": "",
}
My issue is that I want to be able to access a specific invoices of a specific subs.
I am new to Mongo/Mongoose so it is possible I am doing something completely wrong and I would be more than happy with any answer/criticism on how I am approaching this.
-- tweaked answer --
Job.aggregate([
{
$match: {
"_id": mongoose.Types.ObjectId(req.body.jobID)
}
},
{
$unwind: "$subs"
},
{
$match: {
"subs._id": mongoose.Types.ObjectId(req.body.subID)
}
},
{
$unwind: "$subs.invoices"
},
{
$match: {
"subs.invoices._id": mongoose.Types.ObjectId(req.body.invID)
}
},
{
$project: {
"_id": 1,
"subs.invoices": 1
}
}
], function(err, job) {
if (err) throw err;
res.send(job);
});
You can try below aggregation...
Here this is a long process of deconstructing an array using $unwind and rebuild the array using $group
db.collection.aggregate([
{ "$match": { "_id": "1111" } },
{ "$unwind": "$subs" },
{ "$match": { "subs._id": "2222" } },
{ "$unwind": "$subs.invoices" },
{ "$match": { "subs.invoices._id": "3333" } },
{ "$group": {
"_id": {
"_id": "$_id",
"subs": "$subs._id"
},
"firstName": { "$first": "$firstName" },
"lastName": { "$first": "$lastName" },
"address": { "$first": "$address" },
"subs": {
"$first": {
"_id": "$subs._id",
"email": "$subs.email",
"venue": "$subs.venue",
"scope": "$subs.scope"
}
},
"invoices": { "$push": "$subs.invoices" }
}},
{ "$group": {
"_id": "$_id._id",
"firstName": { "$first": "$firstName" },
"lastName": { "$first": "$lastName" },
"address": { "$first": "$address" },
"subs": {
"$push": {
"_id": "$subs._id",
"email": "$subs.email",
"venue": "$subs.venue",
"scope": "$subs.scope",
"invoices": "$invoices"
}
}
}}
])
Or you can do this with $filter aggregation as well
db.collection.aggregate([
{ "$match": { "_id": "5b1586ccf0c56353e89d330b" }},
{ "$unwind": "$subs" },
{ "$match": { "subs._id": "5b1fc7f23b595481d4599f58" }},
{ "$project": {
"address": 1, "firstName": 1, "lastName": 1,
"subs.type": "$subs._id",
"subs.status": "$subs.email",
"subs.code": "$subs.scope",
"subs.invoices": {
"$filter": {
"input": "$subs.invoices",
"as": "invoice",
"cond": {
"$eq": [
"$$invoice._id",
"5b1fca54e6ee1d80c463612b"
]
}
}
}
}},
{ "$group": {
"_id": "$_id",
"address": { "$first": "$address" },
"firstName": { "$first": "$firstName" },
"lastName": { "$first": "$lastName" },
"subs": { "$push": "$subs" }
}}
])