1

I have post schema like this

const postSchema = new mongoose.Schema({
  title: { type: String, minlength: 2 },
  description: { type: String },
  categoryId: [{ type: mongoose.Schema.ObjectId, ref: "category" }],
});

I have to fetch random documents from the posts and populate all categories in it. What I have achieved so far is this

await Post.aggregate([
      {
        $lookup: {
          from: "categories",
          localField: "categoryId",
          foreignField: "_id",
          as: "categoryId",
        },
      },
    ]).sample(5)

Need to do

Suppose i have an id of a category in a variable catId, what I need to do is to filter out those posts which contains this id in their array of categoryId before getting those random posts. By filtering out I mean i need random posts which has catId in their array.

mav-raj
  • 751
  • 1
  • 7
  • 20

1 Answers1

1

You can do it like below :

Post.aggregate([
  /** Use match to Get docs where 'categoryId' has passed in value */
  {
    $match: {
      categoryId: catId /** Input 'catId', make sure you convert input request of string to 'ObjectId()' to match with type in DB*/
    }
  },
  {
    $sample: { /** Picks some random 3 docs (Sometimes a single doc can be repeated) */
      size: 3
    }
  },
  {
    $lookup: {
      from: "categories",
      localField: "categoryId",
      foreignField: "_id",
      as: "categoryId"
    }
  }
])

Test : MongoDB-Playground

Ref : $sample

Note : So $sample can get the job done, but it has few limitations read through the doc for more info. Use $explain to check if your query is performing well or not, In any case if $sample is not working for you, then you can actually use $skip & $limit to get this job done.

Let's say if you can auto generate some number at least 3 less than collections size for skip & skip those docs to eventually do limit of 3 on remaining docs. You can have a sort in between skip & limit - such way do test this for better uniqueness. Check this : skip-and-limit-in-aggregation-framework - Usually this used for pagination but might help you in least case.

whoami - fakeFaceTrueSoul
  • 17,086
  • 6
  • 32
  • 46
  • 1
    Thanks a ton. I actually wrote this one after googling and reading docs, but lost to converting id to ObjectId(). – mav-raj Apr 07 '20 at 19:25