Затем вставьте вложенные документы

#javascript #node.js #mongodb #mongoose #graphql

#javascript #node.js #mongodb #мангуст #graphql

Вопрос:

У меня есть объект order с массивом элементов order. Возможно, некоторые из этих элементов еще не были созданы, поэтому я хотел бы обновить элементы, а затем добавить все элементы в заказ. Ниже приведено то, что я пытаюсь сделать в своем преобразователе GraphQL, но я не могу then подключиться 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;
}
 

Результат для карты не разрешается, если используется отдельно.

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

Я думаю, что bulkWrite — это то, что мне нужно, но я не могу понять, как вернуть документы из bulkWrite вместо количества измененных документов. Без новых / обновленных документов я не знаю, как привести их в порядок.

Комментарии:

1. Никогда не читал это слово upsert до сегодняшнего дня. Как странно.

2. promise.all, используйте поиск

Ответ №1:

Вы можете использовать .map с Promise.all, чтобы дождаться завершения всех обновлений, а затем, наконец, обновить порядок. Второй блок кода может быть обновлен примерно до следующего:

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

Комментарии:

1. Спасибо! Для тех, кто делает что-то подобное, я забыл вернуться с карты: const updatedItems = await Promise.all( items.map(async ({id, …item }) => { return await OrderItem.findByIdAndUpdate( id, { … item }, { new: true, upsert: true, setDefaultsOnInsert: true } ); }) );

2. Спасибо вам за комментарий. Обновленный ответ, чтобы вернуть обещание с карты.