如何在 MongoDB V4.4 中绕过其每个管道的 $facet 内存 100MB 内存限制?

How to bypass $facet memory 100MB memory limit on each of its pipeline in MongoDB V4.4?

我正在使用 MongoDB 3.4,最近在 Beta 环境中将其升级到 4.4。我有一个使用 facet 的查询,它超出了 100MB 的大小限制 issue.I 看到 Jira link 在这里解释了这个问题:https://jira.mongodb.org/browse/SERVER-40317

查询是根据用户输入动态生成的,因此很难直接对查询进行更改我认为这是最后的手段。

无论如何我都在寻找绕过这个限制的方法。 AllowDiskUsage 也不起作用,如上文所述 link.

你必须像这样使用 mongoose utils allowdiskusage:

return OrderEntity
        .aggregate(compendiumAggregation(query))
        .allowDiskUse(true)
        .then(success(res))
        .catch(next);

已确认这可以解决问题:

  db.adminCommand({setParameter: 1, internalQueryFacetMaxOutputDocSizeBytes: 335544320})

使用上述命令影响的 RAM 限制从默认的 100MB 更改为 320MB

查看更改是否到位:

 use admin
 db.runCommand( { getParameter : 1, “internalQueryFacetMaxOutputDocSizeBytes” : 1 } )

此更改是临时的,要使其永久化,您需要添加到 mongodb.conf 文件以在启动时生效:

 setParameter:
     internalQueryFacetMaxOutputDocSizeBytes: 335544320

与您的问题不完全相关,但您的聚合管道看起来有点傻。你到底为什么要用所有这些 $and / $or 只有一个参数?

如果我没记错的话,你的聚合管道是这样的:

responses.aggregate([
   {
      '$match': {
         surId: '5f548bda279ef41b7a9cd23c',
         preview: 0,
         resStatus: '1',
         archive: { '$exists': false },
         modified: {
            '$gte': ISODate('2020-08-31T20:59:59.999Z'),
            '$lt': ISODate('2020-11-30T21:00:00.000Z')
         },
         'resAObj.601aaf29fd93f74cab932141': { $in: [Object] }
      }
   },
   { $project: { 'resAObj.601aaf29fd93f74cab932141': 1, surId: 1 },
   {
      '$facet': {
         '0': [
            { '$match': { 'resAObj.601aaf29fd93f74cab932141': { '$elemMatch': [Object] } } },
            { '$addFields': { 'resAObj.601aaf29fd93f74cab932141': { '$filter': { input: '$resAObj.601aaf29fd93f74cab932141', as: 'item', cond: { '$and': [Array] } } } } },
            {
               '$project': {
                  surId: '$surId',
                  d_DMID7235_0_d: { '$filter': { input: '$resAObj.601aaf29fd93f74cab932141', as: 'dmi_0', cond: { '$eq': [Array] } } },
                  d_DMID7237_0_d: { '$filter': { input: '$resAObj.601aaf29fd93f74cab932141', as: 'dmi_0', cond: { '$eq': [Array] } } },
                  d_DMID7239_0_d: { '$filter': { input: '$resAObj.601aaf29fd93f74cab932141', as: 'dmi_0', cond: { '$eq': [Array] } } },
                  d_DMID7240_0_d: { '$filter': { input: '$resAObj.601aaf29fd93f74cab932141', as: 'dmi_0', cond: { '$eq': [Array] } } },
                  d_DMID7241_0_d: { '$filter': { input: '$resAObj.601aaf29fd93f74cab932141', as: 'dmi_0', cond: { '$eq': [Array] } } },
                  d_DMID7242_0_d: { '$filter': { input: '$resAObj.601aaf29fd93f74cab932141', as: 'dmi_0', cond: { '$eq': [Array] } } },
                  d_DMID7243_0_d: { '$filter': { input: '$resAObj.601aaf29fd93f74cab932141', as: 'dmi_0', cond: { '$eq': [Array] } } },
                  d_DMID7244_0_d: { '$filter': { input: '$resAObj.601aaf29fd93f74cab932141', as: 'dmi_0', cond: { '$eq': [Array] } } },
                  d_DMID7245_0_d: { '$filter': { input: '$resAObj.601aaf29fd93f74cab932141', as: 'dmi_0', cond: { '$eq': [Array] } } },
                  index: '0'
               }
            },
            {
               '$project': {
                  surId: '$surId',
                  DMID7235: { '$ifNull': ['$d_DMID7235_0_d', 0] },
                  DMID7237: { '$ifNull': ['$d_DMID7237_0_d', 0] },
                  DMID7239: { '$ifNull': ['$d_DMID7239_0_d', 0] },
                  DMID7240: { '$ifNull': ['$d_DMID7240_0_d', 0] },
                  DMID7241: { '$ifNull': ['$d_DMID7241_0_d', 0] },
                  DMID7242: { '$ifNull': ['$d_DMID7242_0_d', 0] },
                  DMID7243: { '$ifNull': ['$d_DMID7243_0_d', 0] },
                  DMID7244: { '$ifNull': ['$d_DMID7244_0_d', 0] },
                  DMID7245: { '$ifNull': ['$d_DMID7245_0_d', 0] },
                  index: '0'
               }
            }
         ],
         '1': ['... same as above'],
         '2': ['... same as above'],
         '3': ['... same as above'],
         '4': ['... same as above'],
         '5': ['... same as above'],
         '6': ['... same as above'],
         '7': ['... same as above'],
         total: [{ '$count': 'total' }],
         baseValue: ['... same as above']
      }
   },
   { '$project': { mergedArray: { '$concatArrays': ['[=10=]', '', '', '', '', '', '', '', '$total', '$baseValue'] } } },
   { '$unwind': '$mergedArray' },
   { '$replaceRoot': { newRoot: '$mergedArray' } }
])

你所有的操作都基于一个字段resAObj.601aaf29fd93f74cab932141,这看起来很奇怪。也许纯 javascript 代码可以更好地解决它。

您可以使用 $map, $arrayToObject and $objectToArray。实际上我根本看不出使用 $facet 的原因。

没有样本输入数据和样本结果很难给出答案,但我认为聚合管道可以写得更简单。