2

I have an old list of products that store the descriptions in an array at index [0]. The model is set up as a string. So my plan is to extract that value and add it to a temporary field. Step 2 would be to take that value and copy it to the original field. This is the 'wrong' product I want to fix.

{_id : 1 , pDescription : ['great product']},
{_id : 2 , pDescription : ['another product']}

All I want to is to change the array to a string like this:

{_id : 1 , pDescription : 'great product'},
{_id : 2 , pDescription : 'another product'}

I have tried this to create the temporary description:

    Products.aggregate([
    {
        $match: {
            pDescription: {
                $type: "array"
            }
        }
        },
    {
        $set: {
            pDescTemp: {
                $first: "$pDescription"
            }
        }
            }
        ]).exec((err, r) => {
       // do stuff here
   });

The command works fine without the $first command. The error reads: MongoError: Unrecognized expression '$first'

Any tips on how to fix this are appreciated! Thanks!

1 Answer 1

2

I believe this is what you need to update your pDescription field to be equal to the first element of the array already stored as pDescription:

db.Products.updateMany({},
[
  {
    $set: {
      pDescription: {
        $arrayElemAt: [
          "$pDescription",
          0
        ]
      }
    }
  }
])
Sign up to request clarification or add additional context in comments.

5 Comments

Fantastic. Thank you so much codemonkey!!
@Caldera500 No problem. Just remember that aggregation in and of itself does not update anything, it's just a tool to accumulate and display data, so Products.aggregate is not the way to go. Rather you need an aggregation pipeline inside an update operator.
This makes totally sense. During my research I found out that you can combine aggregation with updates. I guess this is mostly used for other applications. The update call you are describing is much better for my use case. Also extremely elegant and fast. I updated 5k document in less than 0.5 secs. The Mongo docs usually only show the most basic use cases. I guess I still have much to learn here. Thanks again!
How would it need to be altered to store the first element not onto the source itself but to another field? I tried the above but got The dollar ($) prefixed field '$arrayElemAt' in 'plonk.$arrayElemAt' is not valid for storage. Here, plonks is my array to copy the first element from and plonk is the field to store it in.
@KonradViltersten If I understand you correctly, here is what you need: mongoplayground.net/p/iiEkmA8ecMU

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.