skip to Main Content

In Mongoose, you can write a statement like the following, to return documents with restricted fields, and only 10 of them. This returns the same 10 documents every time, which is expected.

products = await Product.find({
        category: category,
      })
        .select("title img price desc category postageCost")
        .limit(10);

I would like to show random products on page load and the mongoose .sample() method is perfect, so I wrote this:

products = await Product.find({
        category: category,
      })
        .select("title img price desc category postageCost")
        .sample(10);

I can’t seem to make it work as I would expect though. Instead I had to run Product.find().sample(10) and then modify the object returned, to only return the "title img price desc category postageCost" fields.

Is it possible to combine select() and sample() with Mongoose or is my method the only way to return random fields and restrict the contents of the returned documents?

2

Answers


  1. You should use sample method with mongoose aggregate function, and then use project method to retrieve specific data.

        const selectedFeilds = "title img price desc category postageCost";
    
        Product.aggregate([{ $sample: { size: 10 } }, // Select a random document
      { $project: {...selectedFields.split(' ').reduce((acc, field) => ({ ...acc, [field]: 1 }), {}) } } // Project to select specific fields
    ])
    
    Login or Signup to reply.
  2. You need to chain the sample() function as a method of the Model.aggregate function but after you call the match() method. The Model.aggregate.match() method is synonymous with a Model.find().

    Here is an example:

    const products = await Product.aggregate()
        .match({category: category})
        .project("title img price desc category postageCost")
        .sample(10);
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search