【问题标题】:Mongodb aggregation pass argument to element size of $sampleMongodb 聚合将参数传递给 $sample 的元素大小
【发布时间】:2021-03-04 05:07:17
【问题描述】:

大家好,这里的任何人都可以帮助我进行以下查询

  • 我想获取随机数量的测验列表
  • rendom 的数量将 以每节课为基础

问题是

  • mongodb 不允许将参数传递给 $sample 的元素大小

任何人都可以给我解决方案

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();

错误说 $sample 的 size 参数必须是数字

这是我的示例数据

【问题讨论】:

  • 从您的lessons 收藏或lessonModel 发布一些数据
  • 请使用Mongo Playground分享您的示例数据和查询:)
  • @DheemanthBhat 我在帖子中添加了示例数据
  • @ray 我已经在我的帖子中更新了请检查
  • @DaraVichit 检查更新的答案是否有助于您随机选择amount 数量的quiz 的实际问题。

标签: mongodb mongoose aggregation-framework


【解决方案1】:

更新

我认为您的主要问题是在每节课下随机选择amount 数量的quizs。由于$sample 没有帮助,请使用$function(MongoDB 4.4 版本中的新功能)。

解决方案

在$function操作符里面写一些逻辑到

  1. Shuffle the questions(您可以根据自己的需要更改)。
  2. 将其切片以返回所需问题的数量 (amount)。
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 不支持变量。必须明确指定一个数字,如:

{ 
    $sample: { size: 1 }
}

同时替换您的let,如下所示,因为最后一个lesson 文档在quiz 对象中没有amount 归档

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

错误:

{ 
    $sample: { size: "$$limit" } // Wont work!
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-07-12
    • 1970-01-01
    • 2017-12-04
    • 1970-01-01
    • 2023-01-07
    • 1970-01-01
    • 1970-01-01
    • 2013-11-22
    相关资源
    最近更新 更多