Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

170
Vistas
Mongodb aggregation pass argument to element size of $sample

Hello every body here any one can help me with query below

  • I want to get quiz list with random amount
  • the amount of rendom will base on each lesson

The problem is

  • mongodb not allow to pass argument to element size of $sample

Any one can give me the solution

lessonModel.aggregate([
        { $match : {'quiz.status':1 } },
        {
            $lookup : {
                from : 'quiz',
                let : { 'lesson_id' : '$_id','limit' : '$quiz.amount' },
                pipeline : [
                    { 
                        $match: { 
                            $expr: { 
                                $eq: [ "$lesson_id", "$$lesson_id" ]
                            } 
                        } 
                    },
                    { 
                        $project: {
                            title:1,
                            check_list:1,
                            duration:1
                        }               
                    },
                    { $sample: { size: '$$limit' } }
                ],
                as: 'quiz'
            }
        }, 
        {$unwind: '$quiz'},
        { $replaceRoot: { newRoot: "$quiz" } }
    ]).exec();

The error said size argument to $sample must be a number

Here is my sample data Sample data

over 4 years ago · Santiago Trujillo
1 Respuestas
Responde la pregunta

0

UPDATE

I think your main problem is to randomly pick amount number of quizs under each lesson. Since $sample is not helpful use $function (New in version MongoDB 4.4).

Solution

Inside $function operator write some logic to

  1. Shuffle the questions (You can change it to your requirement).
  2. Slice it to return the number(amount) of questions required.
db.lessons.aggregate([
    { $match: { "quiz.status": 1 } },
    {
        $lookup: {
            from: "quiz",
            let: { "lesson_id": "$_id" },
            pipeline: [
                {
                    $match: {
                        $expr: { $eq: ["$lesson_id", "$$lesson_id"] }
                    }
                },
                {
                    $project: {
                        title: 1,
                        check_list: 1,
                        duration: 1
                    }
                }
            ],
            as: "questions"
        }
    },
    {
        $project: {
            quiz: {
                $function: {
                    body: function(questions, amount) {
                        if (amount == 0) return [];

                        for (let i = questions.length - 1; i > 0; i--) {
                            const j = Math.floor(Math.random() * (i + 1));
                            [questions[i], questions[j]] = [questions[j], questions[i]];
                        }

                        return questions.slice(0, amount);
                    },
                    args: ["$questions", { $ifNull: ["$quiz.amount", 0] }],
                    lang: "js"
                }
            }
        }
    },
    { $unwind: "$quiz" },
    { $replaceRoot: { newRoot: "$quiz" } }
]);

$sample does not support variables. A number must be specified explicitly like:

{ 
    $sample: { size: 1 }
}

Also replace your let as shown below because last lesson document has no amount filed in the quiz object

let: {
    'lesson_id': '$_id',
    'limit': { $ifNull: ['$quiz.amount', 0] } // or any other number.
},

Wrong:

{ 
    $sample: { size: "$$limit" } // Wont work!
}
over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda