Home > other >  Out new collection with sequence numeric id after stages in mongodb aggregate
Out new collection with sequence numeric id after stages in mongodb aggregate

Time:03-23

I'm trying to out a collection, after some stages in the MongoDB aggregation pipeline. the out collection needs to contain an id with sequence numeric id (1,2,3,4 etc...).

db.getCollection('MY_COLLECTION').aggregate([{
    $addFields: {
      "dataEntries.targetCol1": "$dataEntries.col1",
      "dataEntries.targetCol2": "$dataEntries.col2"
    }
  },
  {
    $project: {
      "_id": 0,
      "dataEntries.col1": 0,
      "dataEntries.col2": 0,
      "dataEntries.col3": 0,
      "dataEntries.col4": 0
    }
  },
  {
    $unionWith: {
      coll: "MY_COLLECTION",
      pipeline: [{
          $addFields: {
            "dataEntries.targetCol1": "$dataEntries.col3",
            "dataEntries.targetCol2": "$dataEntries.col4"
          }
        },
        {
          $project: {
            "_id": 0,
            "dataEntries.col1": 0,
            "dataEntries.col2": 0,
            "dataEntries.col3": 0,
            "dataEntries.col3": 0
          }
        }
      ]
    }
  },
  {
    $out: "test_out"
  }
])

The result collection contains an objectId as the id.

/* 1 */
{
    "_id" : ObjectId("6239cb749482cf6b13248a80"),
    "dataEntries" : {
        "targetCol1" : "101-A",
        "targetCol2" : "101"
    }
}

/* 2 */
{
    "_id" : ObjectId("6239cb749482cf6b13248a81"),
    "dataEntries" : {
        "targetCol1" : "101-B",
        "targetCol2" : "101"
    }
}

There is a way to set the id to sequence numeric counter for every document? The expected results:

/* 1 */
{
    "_id" : 1,
    "dataEntries" : {
        "targetCol1" : "101-A",
        "targetCol2" : "101"
    }
}

/* 2 */
{
    "_id" : 2,
    "dataEntries" : {
        "targetCol1" : "101-B",
        "targetCol2" : "101"
    }
}

CodePudding user response:

In MongoDB 5.0 it is very simple:

db.collection.aggregate([
   {
      $setWindowFields: {
         sortBy: { _id: 1, },
         output: { _id: { $documentNumber: {} } }
      }
   }
])

In earlier versions, it is a little more to do:

db.collection.aggregate([
   {
      $group: {
         _id: null, data: { $push: "$$ROOT" }
      }
   },
   {
      $set: {
         data: {
            $map: {
               input: "$data",
               in: {
                  $mergeObjects: ["$$this",
                     { _id: {$add: [{ $indexOfArray: ["$data._id", "$$this._id"] }, 1]} }
                  ]
               }
            }
         }
      }
   },
   { $unwind: "$data" },
   { $replaceWith: "$data" }
])
  • Related