Home > Blockchain >  Return $sample result as appended JSON key MongoDB
Return $sample result as appended JSON key MongoDB

Time:12-23

I perform a query to find one specific record by ID in MongoDB. It works fine, and returns me the following document:

{
   key1: "value1",
   key2: "value2"
}

Now I need to add to the returned JSON record the key "seeAlso".

This key will contain a sample of 3 other records in the same collection.

The final document should look like it:

{
   key1: "value1",
   key2: "value2",
   seeAlso: [
      {doc1},
      {doc2},
      {doc3},
   ]
}

The $sample I already know how to do. Gotta add the following to the pipeline:

  {
    '$sample': {
      'size': 10
    }
  }

What I don't know yet is how to store the result of this sample in the "seeAlso" key. Such key needs to be created at this point, it doesn't yet exist.

CodePudding user response:

You may just need to do the $sample in a subpipeline. To leave out the original record, add a $match at the start of the subpipeline to leave out by _id

db.collection.aggregate([
  {
    "$match": {
      key1: "value1"
    }
  },
  {
    "$lookup": {
      "from": "collection",
      "let": {
        id: "$_id"
      },
      "pipeline": [
        {
          $match: {
            $expr: {
              $ne: [
                "$_id",
                "$$id"
              ]
            }
          }
        },
        {
          "$sample": {
            "size": 3
          }
        }
      ],
      "as": "seeAlso"
    }
  }
])

Mongo Playground

CodePudding user response:

You could do this with $facet with stages:

  • $facet with 2 pipelines:
    pipeline1: $match the single document
    pipeline2:
    • $sample to select the number of documents you want plus 1
    • $match to exclude the document selected in pipeline 1 (just in case)
    • $limit to return the number of documents you want
  • $unwind pipeline1
  • $project to add pipeline2 to a field in the document pipeline1
  • $replaceRoot to make pipeline1 the top-level document
  • Related