pa1nd
pa1nd

Reputation: 442

Mongodb: Create embedded document - get Id

I'm trying to implement a simple CRUD Create for an embedded document.

The URL is like this [POST] /restaurants/:id/subsidiaries

The query looks like this:

const restaurant = await Restaurant.findByIdAndUpdate(req.params.id, {
  $push: {
    subsidiaries: {
      phone,
      email,
      title,
      ...
    },
  },
})

I'm using mongoose - so this automatically creates an id for the subsidary.

I now want to return the newly created subsidary (including the ID). Given that I don't have any other identifier in my data - how can I find which is the newly created document?

I know that Mongo encourages embedding documents - but I could not find any information about how to handle typical (I find that a very typical case) REST/CRUD problems.

Upvotes: 0

Views: 357

Answers (2)

pa1nd
pa1nd

Reputation: 442

It is also possible to add the document as the first child into the array (newest first order).

We can use $position: 0 to achieve this - but it also requires to put the embedded document into the $each: [] array.

There's the code:

const restaurant = await Restaurant.findByIdAndUpdate(
  req.params.id,
  {
    $push: {
      subsidiaries: {
        $each: [
          {
            phone,
            email,
            title,
            ...
          },
        ],
        $position: 0,
      },
    },
  },
  { new: true }
)

if (!restaurant) return res.sendStatus(500)

const subsidiary = restaurant.subsidiaries[0]
res.send(subsidiary)

Upvotes: 0

pa1nd
pa1nd

Reputation: 442

The answer can be found in the mongodb $push modifiers documentationhttps://docs.mongodb.com/manual/reference/operator/update/push/#modifiers

Without the $position modifier, the $push appends the elements to the end of the array.

So as we know, the added element will be the last one in the returned array of embedded documents.

// Question
const restaurant = await Restaurant.findByIdAndUpdate(req.params.id, {
  $push: {
    subsidiaries: {
      phone,
      email,
      title,
      ...
    },
  },
}, { new: true })

// Answer
if (!restaurant) return res.sendStatus(500)

const newlyCreatedSubsidiary = restaurant.subsidiaries.slice(-1)[0]
res.send(newlyCreatedSubsidiary)

Don't forget to wrap this into a try-catch 😉.

Upvotes: 0

Related Questions