I have a collection with following schema –
const ContentSchema = new Schema({
label: {
type: String
},
itemId: {
type: Schema.ObjectId,
refPath: 'onModel'
},
formId: {
type: Schema.ObjectId,
refPath: 'onModel'
},
value: {
type: Schema.Types.Mixed,
index: "text"
},
}, { timestamps: true, versionKey: false });
Here are some example documents the collection may have –
{
_id: ObjectId('647b1538c29a553ad6e8f316'),
label: "Name",
itemId: ObjectId('647b1538c29a553ad6e8f313'),
formId: ObjectId('647b1538c29a553ad6e8f913'),
value: "ABC"
},
{
_id: ObjectId('647b1538c29a553ad6e8f416'),
label: "Email",
itemId: ObjectId('647b1538c29a553ad6e8f313'),
formId: ObjectId('647b1538c29a553ad6e8f913'),
value: "def@mail.com"
},
{
_id: ObjectId('647b1538c29a553ad6e8f516'),
label: "Name",
itemId: ObjectId('647b1538c29a553ad6e8f320'),
formId: ObjectId('647b1538c29a553ad6e8f913'),
value: "MNO"
},
{
_id: ObjectId('647b1538c29a553ad6e8f616'),
label: "Email",
itemId: ObjectId('647b1538c29a553ad6e8f320'),
formId: ObjectId('647b1538c29a553ad6e8f913'),
value: "xyz@mail.com"
}
Now, I need to perform a query to search "ABC" from the collection with formId – ObjectId('647b1538c29a553ad6e8f913').
Here is the code to do that –
return await ContentModel.aggregate([
{
$match: {
$text: { $search: text },
formId: new mongoose.Types.ObjectId(formId)
}
}]
The above code is absolutely working fine and returns the document –
{
_id: ObjectId('647b1538c29a553ad6e8f316'),
label: "Name",
itemId: ObjectId('647b1538c29a553ad6e8f313'),
formId: ObjectId('647b1538c29a553ad6e8f913'),
value: "ABC"
}
But I need more records within the same aggregation. Now I need to find out other documents from the document with itemId – ObjectId('647b1538c29a553ad6e8f313').
So that the aggregation should now return 2 documents –
{
_id: ObjectId('647b1538c29a553ad6e8f316'),
label: "Name",
itemId: ObjectId('647b1538c29a553ad6e8f313'),
formId: ObjectId('647b1538c29a553ad6e8f913'),
value: "ABC"
},
{
_id: ObjectId('647b1538c29a553ad6e8f416'),
label: "Email",
itemId: ObjectId('647b1538c29a553ad6e8f313'),
formId: ObjectId('647b1538c29a553ad6e8f913'),
value: "def@mail.com"
}
I am trying with following query which does not work –
return await ContentModel.aggregate([
{
$match: {
$text: { $search: text },
formId: new mongoose.Types.ObjectId(formId)
}
},
{
$match: { itemId: "$itemId" }
}]
>Solution :
If I’ve understood correctly you can use $lookup with your own collection in this way:
In this query you can $match as you have done and then, with matching results you can $lookup (like a SQL JOIN) against your data using collection and matching itemId.
So is like to say "join the matching itemId with all others itemId". And I think is what you want.
db.collection.aggregate([
{
"$match": { /* your match*/ }
},
{
"$lookup": {
"from": "collection",
"localField": "itemId",
"foreignField": "itemId",
"as": "results"
}
},
{
"$unwind": "$results"
},
{
"$replaceRoot": {
"newRoot": "$results"
}
}
])
Also the two others steps are to output the result as root.
Example here