$concat field with index in $map mongodb? [duplica

2019-03-06 15:26发布

问题:

This question already has an answer here:

  • Add some kind of row number to a mongodb aggregate command / pipeline 1 answer

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!!!

回答1:

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
    }
}])