Reputation: 21
I want have the field contractType in my mongoose schema, is an array of objects that each one has the property authorizedBy into the second level.
contractType field could have many items and I want to know each authorizedBy finding it in other collection called admins (I'll let it below too).
const professionalSchema = new Schema(
firstName: String,
contractType: [
new Schema(
{
contract: String,
authorizedBy: {
type: ObjectId,
ref: 'admin',
index: true,
},
document: String
},
{
timestamps: true,
versionKey: false,
},
),
],
)
this is my admin collection.
const adminSchema = new Schema(
{
firstName: String,
lastName: String,
role: String
},
{
timestamps: true,
versionKey: false,
},
)
I have this in professionalSchema mongodb compass:
{
"_id": ObjectId("6009a0d0874f0900086ee0ce"),
"firstName": "xxxx",
"gender": "NOT_SPECIFIED",
"contractType": [
{
"authorizedBy": ObjectId("5fad90665d963cbbbd4a6580"),
"document": "document 1"
},
{
"authorizedBy": ObjectId("5fad90665d963cbbbd4a6580"),
"document": "document 2"
}
]
}
this is an admin of the collection of admins (adminSchema):
{
"_id": ObjectId("5fad90665d963cbbbd4a6580"),
"role": "SAM",
"firstName": "firstname",
"lastName": "lastname"
}
I would have response like this one below, additionally I want to get all fields of the object (20 aprox) not adding each one manually, like spread operator (...item) in javascript
{
"_id": ObjectId("6009a0d0874f0900086ee0ce"),
"firstName": "xxxx",
"contractType": [
{
"authorizedBy": {
"_id": "5fad90665d963cbbbd4a6580",
"firstName": "firstname",
"lastName": "lastname",
"role": "SAM"
},
"document": "document 1"
},
{
"authorizedBy": {
"_id": "5fad90665d963cbbbd4a6580",
"firstName": "firstname",
"lastName": "lastname",
"role": "SAM"
},
"document": "document 2"
}
]
}
I tried this in mongo compass.
[
{
'$match': {
'_id': new ObjectId('6009a0d0874f0900086ee0ce')
}
}, {
'$unwind': {
'path': '$contractType'
}
}, {
'$lookup': {
'from': 'admins',
'localField': 'contractType.authorizedBy',
'foreignField': '_id',
'as': 'contractType.authorizedBy'
}
}, {
'$unwind': {
'path': '$contractType.authorizedBy'
}
}, {
$group': {
'_id': '$_id'
}
}
]
but I don't know how put rest of elements (20 aprox) in the same object :(
Upvotes: 2
Views: 530
Reputation: 8894
What you have done is almost correct,
db.professionalSchema.aggregate([
{"$match": {"_id": ObjectId("6009a0d0874f0900086ee0ce") } },
{"$unwind": {"path": "$contractType" }},
{
"$lookup": {
"from": "adminSchema",
"localField": "contractType.authorizedBy",
"foreignField": "_id",
"as": "contractType.authorizedBy"
}
},
{
"$addFields": {
"contractType.authorizedBy": {
$ifNull: [
{ $arrayElemAt: [ "$contractType.authorizedBy", 0 ] },
""
]
}
}
},
{
"$group": {
"_id": "$_id",
"firstName": { $first: "$firstName" },
"gender": { $first: "$gender"},
contractType: { $push: "$contractType" }
}
}
])
Working Mongo playground
Upvotes: 1