简体   繁体   中英

Upsert subdocuments then

I have an order object with an array of order items. Some of these items may not have been created yet so I would like to upsert the items, then add all of the items to the order. Below is what I am trying to do in my GraphQL resolver but I cannot chain then to map .

updateOrder: async (_, { order: { id, items, ...order } }, { req }) => {


        const updatedOrder = items
          .map(async ({ id, ...item }) => {
            await OrderItem.findByIdAndUpdate(
              id,
              { ...item },
              { new: true, upsert: true, setDefaultsOnInsert: true }
            );
          })
          .then(
            async (res) =>
              await Order.findByIdAndUpdate(
                id,
                { items: res, ...order },
                { new: true }
              )
          );

        return updatedOrder;
}

The result for the map does not resolve if used separately.

const updatedItems = items
          .map(async ({ id, ...item }) => {
            await OrderItem.findByIdAndUpdate(
              id,
              { ...item },
              { new: true, upsert: true, setDefaultsOnInsert: true }
            );
          })

const updatedOrder = await Order.findByIdAndUpdate(
                id,
                { items: updatedItems, ...order },
                { new: true }
              )
          );

I think bulkWrite is what I need but I cannot figure out how to return the documents from the bulkWrite instead of the counts of modified documents. Without the new/updated documents, I don't know how to push them to the order.

You can use.map with Promise.all to wait till all upsert's are completed and then finally update order. Second block of code can be updated to something like below:

const updatedItems = await Promise.all(
  items.map(async ({ id, ...item }) => {
    return OrderItem.findByIdAndUpdate(
      id,
      { ...item },
      { new: true, upsert: true, setDefaultsOnInsert: true }
    );
  })
);

const updatedOrder = await Order.findByIdAndUpdate(
  id,
  { items: updatedItems, ...order },
  { new: true }
)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM