3

I have following collection

{
    "_id" : ObjectId("5b16405a8832711234bcfae7"),
    "createdAt" : ISODate("2018-06-05T07:48:45.248Z"),
    "firstName": "Bruce",
    "lastName": "Wayne"
},
{
    "_id" : ObjectId("5b16405a8832711234bcfae8"),
    "createdAt" : ISODate("2018-06-05T07:48:45.248Z"),
    "firstName": "Clerk",
    "lastName": "Kent"
},
{
    "_id" : ObjectId("5b16405a8832711234bcfae9"),
    "createdAt" : ISODate("2018-06-05T07:48:45.248Z"),
    "firstName": "Peter",
    "lastName": "Parker"
}

I need to $project one more key index with $concat with 'INV-00' + index of the root element

My output should be something like that

{
    "_id" : ObjectId("5b16405a8832711234bcfae7"),
    "createdAt" : ISODate("2018-06-05T07:48:45.248Z"),
    "firstName": "Bruce",
    "lastName": "Wayne",
    "index": "INV-001"
},
{
    "_id" : ObjectId("5b16405a8832711234bcfae8"),
    "createdAt" : ISODate("2018-06-05T07:48:45.248Z"),
    "firstName": "Clerk",
    "lastName": "Kent",
    "index": "INV-002"
},
{
    "_id" : ObjectId("5b16405a8832711234bcfae9"),
    "createdAt" : ISODate("2018-06-05T07:48:45.248Z"),
    "firstName": "Peter",
    "lastName": "Parker",
    "index": "INV-003"
}

and can I change createdAt format to this Thu Jan 18 2018 using $dateToString or something else???

Thanks in advance!!!

Ashh
  • 44,693
  • 14
  • 105
  • 132
  • how changing the createdAt key format will help you to infer index of a document? Trying to understand what you're trying to do – Atish Jun 15 '18 at 07:21
  • *can I change createdAt format to this Thu Jan 18 2018 using $dateToString or something else* Just want to know can it be possible?... Not related to index part @Astro – Ashh Jun 15 '18 at 07:27
  • This should help: https://docs.mongodb.com/manual/reference/operator/aggregation/group/#group-by-month-day-and-year. – Atish Jun 15 '18 at 07:41

1 Answers1

8

While I would certainly recommend you to do that on the client side as opposed to inside MongoDB, here is how you could get what you want - pretty brute-force but working:

db.collection.aggregate([
    // you should add a $sort stage here to make sure you get the right indexes
{
    $group: {
        _id: null, // group all documents into the same bucket
        docs: { $push: "$$ROOT" } // just to create an array of all documents
    }
}, {
    $project: {
        docs: { // transform the "docs" field
            $map: { // into something
                input: { $range: [ 0, { $size: "$docs" } ] }, // an array from 0 to n - 1 where n is the number of documents
                as: "this", // which shall be accessible using "$$this"
                in: {
                    $mergeObjects: [ // we join two documents
                        { $arrayElemAt: [ "$docs", "$$this" ] }, // one is the nth document in our "docs" array
                        { "index": { $concat: [ 'INV-00', { $substr: [ { $add: [ "$$this", 1 ] }, 0, -1 ] } ] } } // and the second document is the one with our "index" field
                    ]
                }
            }
        }
    }
}, {
    $unwind: "$docs" // flatten the result structure
}, {
    $replaceRoot: {
        newRoot: "$docs" // restore the original document structure
    }
}])
dnickless
  • 10,733
  • 1
  • 19
  • 34
  • 1
    @NeilLunn: a) you seem not to have read my starting disclaimer which is actually the same as what you suggested in your above comment to the question. b) not everybody has billions of documents in their collections. c) the BSON limit which I'm well aware of does not apply inside the aggregation pipeline. – dnickless Jun 15 '18 at 08:02