在 $project mongodb 中添加数字字段

Add number field in $project mongodb

我有一个问题需要在获取数据时插入索引号。首先我有这个数据例如:

[
 {
  _id : 616efd7e56c9530018e318ac
  student : {
     name: "Alpha"
     email: null
     nisn: "0408210001"
     gender : "female" 
  }
 },
 {
  _id : 616efd7e56c9530018e318af
  student : {
     name: "Beta"
     email: null
     nisn: "0408210001"
     gender : "male" 
  }
 }
]

然后我需要这样的输出:

[
 {
  no:1,
  id:616efd7e56c9530018e318ac,
  name: "Alpha",
  nisn: "0408210001"
 },
 {
  no:2,
  id:616efd7e56c9530018e318ac,
  name: "Beta",
  nisn: "0408210002"
 }
]

我试过这段代码,但几乎达到了我的预期。

    {
    '$project': {
      '_id': 0, 
      'id': '$_id', 
      'name': '$student.name', 
      'nisn': '$student.nisn'
    }
  }

但是还是搞不懂怎么加索引号。是否可以在 $project 中进行,或者我必须以其他方式进行?感谢您的努力回答。

你可以使用 $unwind 可以 return 一个索引,像这样:

db.collection.aggregate([
  {
    $group: {
      _id: 0,
      data: {
        $push: {
          _id: "$_id",
          student: "$student"
        }
      }
    }
  },
  {
    $unwind: {path: "$data", includeArrayIndex: "no"}
  },
  {
    "$project": {
      "_id": 0,
      "id": "$data._id",
      "name": "$data.student.name",
      "nisn": "$data.student.nisn",
      "no": {"$add": ["$no",  1] }
    }
  }
])

你可以看到它有效 here .

我强烈建议在这些步骤之前使用一个 $match 步骤,否则您会将整个 collection 分组到一个文档中。

您需要 运行 具有 $setWindowFields stage that allows you to add a new field which returns the position of a document (known as the document number) within a partition. The position number creation is made possible by the $documentNumber operator only available in the $setWindowFields 阶段的管道。

分区可以是一个额外的字段(常量),可以充当 window 分区。

管道的最后阶段是 $replaceWith 步骤,它将 student 嵌入文档提升到 top-level 并将所有输入文档替换为指定文档。

运行 以下聚合将产生所需的结果:

db.collection.aggregate([
    { $addFields: { _partition: 'students' }},
    { $setWindowFields: {
        partitionBy: '$_partition',
        sortBy: { _id: -1 },
        output: { no: { $documentNumber: {} } }
    } },
    { $replaceWith: { 
        $mergeObjects: [ 
            { id: '$_id', no: '$no' }, 
            '$student' 
        ] 
    } }
])