Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

MongoDB – aggregate match field from the previously matched document

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 formIdObjectId('647b1538c29a553ad6e8f913').

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading