1

I am wanting to rename a property in one of our MongoDB collections because it was pluralized where it should be singular. However, when I try this in the Mongo shell:

db.getCollection("customers").updateMany( { _id: {$exists: true} }, { $rename: { "billingOptions.0.paymentCards": "billingOptions.0.paymentCard" } } )

... I get this "cannot be an array element" error:

"errmsg" : "The source field cannot be an array element, 'billingOptions.0.paymentCards' in doc with _id: ObjectId('3d12fefc093r76146ccf50g8') has an array field called 'billingOptions'"

Not sure why this would be a problem, since I'm telling it precisely which array element to target. But, either way, this being the case, what operation can I use to rename this property

Here's an example of the relevant section of the document as it is now:

"billingOptions" : [
    {
        "method" : "private", 
        "paymentCards": {
            "deleted" : false,
            // other props
        }
    }, 
]

And this is what I'd like it to look like after:

"billingOptions" : [
    {
        "method" : "private", 
        "paymentCard": {
            "deleted" : false,
            // other props
        }
    }, 
]

Note that "billingOptions" is a property on the root of the document. All I want to do is rename all instances of "paymentCards" to "paymentCard", since it is a singular object here, rather than an array.

3
  • Do you want to rename paymentCards only from first billingOption (index 0) or from all of them ? Could you share a sample document and expected updated doc ? Commented May 7, 2019 at 16:07
  • Ideally, I would do all of them, not just the first array element. Commented May 7, 2019 at 16:14
  • 1
    I added the document structure above. Commented May 7, 2019 at 16:19

1 Answer 1

2

You need $out to replace existing collection and $addFields with $map to replace existing array in each document

db.customers.aggregate([
    {
        $addFields: {
            billingOptions: {
                $map: {
                    input: "$billingOptions",
                    in: {
                        method: "$$this.method",
                        // other fields
                        paymentCard: "$$this.paymentCards"
                    }
                }
            }
        }
    },
    {
        $out: "$customers"
    }
])
Sign up to request clarification or add additional context in comments.

2 Comments

Ah, okay. And I need to explicitly include all props within a "billingOption" (such as "method"), otherwise those will be wiped out, correct?
@Muirik yes, that's the easiest way

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.