You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MongoDB聚合:如何拼接字符串与数组元素并实现预期输出?

问题描述

现有MongoDB集合结构如下:

[
  {
    "_id": { "$oid": "6332dda58121948311cbdb67" },
    "date": "2022-09-13",
    "file": "xxx",
    "package": 1,
    "userList": [
      { "userName": "user_1", "crDate": "2022.09.28", "boolId": 1 }
    ]
  },
  {
    "_id": { "$oid": "6332dda58121948311cbdb68" },
    "date": "2022-09-13",
    "file": "xxx",
    "package": 2,
    "userList": []
  }
]

期望输出分两种情况:

  1. 所有userList数组为空时:
[
  {
    "_id": "2022-09-13",
    "items": [
      {
        "fileName": "xxx",
        "items": [
          { "package": "1 - na" },
          { "package": "2 - na" }
        ]
      }
    ]
  }
]
  1. userList数组包含对象时:
[
  {
    "_id": "2022-09-13",
    "items": [
      {
        "fileName": "xxx",
        "items": [
          { "package": "1 - user_1" },
          { "package": "2 - na" }
        ]
      }
    ]
  }
]

当前执行的聚合脚本存在以下问题:

db.collection.aggregate([
  {
    $group: {
      _id: {
        "date": "$date",
        "file": "$file",
      },
      "items": {
        $push: {
          "package": {
            $concat: [
              { $toString: "package" },
              " - ",
              {
                $toString: {
                  $arrayElemAt: [ "$userList", 0 ]
                }
              }
            ]
          }
        }
      }
    }
  },
  {
    $group: {
      _id: "$_id.date",
      "items": {
        $push: {
          "fileName": "$_id.file",
          "items": "$items"
        }
      }
    },
  }
])
  • userList非空时抛出错误:Mongo Server error (MongoCommandException): Command failed with error 241 (ConversionFailure): 'Unsupported conversion from object to string in $convert with no onError value',原因是直接对userList的元素(对象)执行$toString,MongoDB不支持将对象转为字符串。
  • userList为空时输出不符合预期,无法返回na标识。
修改后的聚合脚本
db.collection.aggregate([
  // 预处理每个文档的package显示文本
  {
    $addFields: {
      packageText: {
        $concat: [
          { $toString: "$package" },
          " - ",
          // 判断userList是否为空,取第一个元素的userName,否则返回"na"
          {
            $cond: {
              if: { $ne: [{ $size: "$userList" }, 0] },
              then: { $getField: { field: "userName", input: { $arrayElemAt: ["$userList", 0] } } },
              else: "na"
            }
          }
        ]
      }
    }
  },
  // 按date和file分组,收集package项
  {
    $group: {
      _id: { date: "$date", file: "$file" },
      items: { $push: { package: "$packageText" } }
    }
  },
  // 按date分组,整理最终结构
  {
    $group: {
      _id: "$_id.date",
      items: { $push: { fileName: "$_id.file", items: "$items" } }
    }
  }
])
修改说明
  1. 新增$addFields阶段:提前处理每个文档的packageText字段,解决原脚本中直接转换对象的问题:
    • 用$size判断userList是否为空;
    • 非空时通过$arrayElemAt取第一个元素,再用$getField提取userName字段;
    • 为空时直接返回na;
    • 最后通过$concat拼接成目标格式的字符串。
  2. 简化后续分组逻辑:在$group阶段直接使用预处理好的packageText,避免嵌套的复杂表达式,提升可读性和稳定性。

内容的提问来源于stack exchange,提问作者solarenqu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 08:05:55