【问题标题】:MongoDB: $in in aggregation is slow despite the indexMongoDB:尽管有索引,但聚合中的 $in 速度很慢
【发布时间】:2022-01-27 22:12:06
【问题描述】:

我有一组用户(约 8k 文档)和一组作业(约 150k 文档)。我需要使用一个阶段创建一个聚合,该阶段可以找到每个用户被接受的工作(在工作模型中接受的是一个 ObjectIds 数组):

db.getCollection('users')
    .aggregate([
        {
            $lookup: {
                from: 'jobs',
                as: 'jobs',
                let: { accepted: '$_id' },
                pipeline: [
                    {
                        $match: {
                            $expr: {
                                $and: [
                                    { $gte: ['$timestamp', 1643223600] },
                                    { $in: ['$$accepted', '$accepted'] }
                                ]
                            }
                        },
                    },
                ]
            }
        },
    ])

这种聚合非常慢。即使将输出记录的数量限制为 10 也需要大约 1 分钟才能完成。虽然,时间戳大于 1643223600 的作业数量并不多——大约是 3000 个文档。我添加了以下索引:

{timestamp: -1},
{accepted: 1}

但这无济于事。但是,如果我创建数据库的副本并删除所有不满足时间戳条件的班次,则聚合工作得更快(几秒钟)。这是否意味着索引由于某种原因不起作用?如果在作业集合上运行一个简单的查询,并在接受字段上加上一个条件的解释,则表明执行了 IXSCAN

UPD:由于 $in 不适用于复合索引,Mongodb4.4 的解决方法是:

 {
            $lookup: {
                from: 'jobs',
                as: 'jobs',
                localField: '_id',
                foreignField: 'accepted'
            }
        },
        { $match: { $expr: { $ne: [{ $size: '$jobs' }, 0] } } },
        { $unwind: '$jobs' },
        {
            $match: { 'jobs.timestamp': { $gte: 1643223600 } }
        },

【问题讨论】:

    标签: node.js mongodb mongoose indexing aggregation


    【解决方案1】:

    查询
    (需要 MongoDB 5)

    users.aggregate(
    [{"$lookup":
      {"from":"jobs",
       "localField":"_id",
       "foreignField":"accepted",
       "pipeline":[{"$match":{"timestamp":{"$gte":1643223600}}}],
       "as":"jobs"}}])
    

    accepted 上创建多键索引后尝试此操作,如果需要,还可以在timestamp 上尝试。

    聚合 $in 即使在 Mongodb 5 中也无法使用索引,因此未使用。
    有关$expr 和索引使用的信息,请参阅here

    【讨论】:

    • 非常感谢,我从来不知道!我使用的是 MongoDB 4.4,所以做了一个解决方法,发布更新
    猜你喜欢
    • 2021-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-25
    • 2013-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多