Mongodb 从包含约120万条记录的集合中进行Mongo查找查询失败

Mongodb 从包含约120万条记录的集合中进行Mongo查找查询失败,mongodb,aggregation-framework,lookup,Mongodb,Aggregation Framework,Lookup,共有两个集合:警报和警报类型。 警报集合有一个名为:alertTypeId的字段,它是警报类型集合的查找/外键 我需要优化下面的查询,通过加入相应的集合,从Alerts集合中获取数据以及AlertType名称 我使用了聚合函数,如下所示: db.Alerts.aggregate([{ "$match": { "status": { "$ne": -1 },

共有两个集合:警报警报类型警报集合有一个名为:alertTypeId的字段,它是警报类型集合的查找/外键

我需要优化下面的查询,通过加入相应的集合,从Alerts集合中获取数据以及AlertType名称

我使用了聚合函数,如下所示:

db.Alerts.aggregate([{
    "$match": {
        "status": {
            "$ne": -1
        },
        "type": 4
    }
}, {
    "$lookup": {
        "localField": "alertTypeId",
        "from": "AlertTypes",
        "foreignField": "_id",
        "as": "alertTypeRel"
    }
}, {
    "$project": {
        "title": 1,
        "type": 1,
        "alertTypeId": 1,
        "alertTypeRel.alertTypeName": 1,
        "priority": 1,
        "message": 1,
        "status": 1,
        "startDate": 1,
        "createdAt": 1,
        "createdBy": 1,
        "validUntil": 1,
        "errorFlag": 1,
        "extApiId": 1,
        "errorMessage": 1,
        "autoPublish": 1,
        "statusChangedBy": 1
    }
},{
    "$sort": {
        "status": 1,
        "createdAt": -1
    }
}, {
    "$group": {
        "_id": null,
        "count": {
            "$sum": 1
        },
        "results": {
            "$push": "$$ROOT"
        }
    }
}, {
    "$project": {
        "total": "$count",
        "_id": 0,
        "results": {
            "$slice": ["$results", 0, 10]
        }
    }
}], {
    "collation": {
        "locale": "en",
        "strength": 2
    },
    "allowDiskUse": true,
    "cursor": {}
}).pretty();
我也为这些字段编制了索引。对于环境商品:

{
        "v" : 2,
        "key" : {
            "status" : 1,
            "createdAt" : -1
        },
        "name" : "status_1_createdAt_-1"
}
警报警报类型集合中分别有1250543和117条记录。我也尝试了
facet
查询,但也得到了相同的结果:

uncaught exception: Error: command failed: {
    "ok" : 0,
    "errmsg" : "$push used too much memory and cannot spill to disk. Memory limit: 104857600 bytes",
    "code" : 146,
    "codeName" : "ExceededMemoryLimit"
} : aggregate failed :
_getErrorWithCode@src/mongo/shell/utils.js:25:13
doassert@src/mongo/shell/assert.js:18:14
_assertCommandWorked@src/mongo/shell/assert.js:639:17
assert.commandWorked@src/mongo/shell/assert.js:729:16
DB.prototype._runAggregate@src/mongo/shell/db.js:266:5
DBCollection.prototype.aggregate@src/mongo/shell/collection.js:1058:12
@(shell):1:1

谢谢

推送
$$ROOT
对象时,
$group
阶段占用了太多内存,几乎没有修复方法,只需使用
$facet
而不是
$group
$project
阶段

  • 对于分页,您可以使用
    $skip
    $limit
    阶段
  • 要计算文档总数,请使用
    $count
    运算符
  • $facet
    来分离
    结果
    计数
  • $limit
    阶段之后使用
    $lookup
    ,因为我们正在获取10个文档,并且只需要查找10个文档
  • 如果需要,在查找后使用
    $project
你最后的问题是

db.Alerts.aggregate([
  {
    "$match": {
      "status": { "$ne": -1 },
      "type": 4
    }
  },    
  {
    "$sort": {
      "status": 1,
      "createdAt": -1
    }
  },
  {
    $facet: {
      result: [
        { $skip: 0 },
        { $limit: 10 },
        {
          "$lookup": {
           "localField": "alertTypeId",
           "from": "AlertTypes",
           "foreignField": "_id",
           "as": "alertTypeRel"
          }
        },
        {
          "$project": {
            "title": 1,
            "type": 1,
            "alertTypeId": 1,
            "alertTypeRel.alertTypeName": 1,
            "priority": 1,
            "message": 1,
            "status": 1,
            "startDate": 1,
            "createdAt": 1,
            "createdBy": 1,
            "validUntil": 1,
            "errorFlag": 1,
            "extApiId": 1,
            "errorMessage": 1,
            "autoPublish": 1,
            "statusChangedBy": 1
          }
        }
      ],
      count: [{ $count: "total" }]
    }
  } 
], 
{
  "collation": {
    "locale": "en",
    "strength": 2
  },
  "allowDiskUse": true,
  "cursor": {}
})
.pretty();
  • 为了获得更高的性能,您可以在匹配条件字段和排序字段上使用索引,根据您的查询,您可以在
    状态
    类型
    创建数据
    上使用复合索引,查看有关
此查询未经测试


“lak”一词在印度以外并不为人所知。谢谢你的回答。但上述查询耗时5分钟以上。此外,我们无法在查找之前对数据进行排序,因为有时,排序将基于查找集合中的警报类型名称,该名称取决于API中的排序请求参数。您是否可以使用
添加此查询的解释状态。explain('executionStats')
请参阅下面链接中添加的解释统计。请看一看,我不确定,我想你必须问到mongodb论坛,我在之前的评论中提到过。我已经问过了。