MongoDB - найдите и добавьте новое свойство - PullRequest
0 голосов
/ 22 января 2019

Справочная информация: я разрабатываю приложение, которое показывает аналитику для управления запасами.Он получает загруженный офисный файл EXCEL, и, когда файл загружает приложение, преобразует его в массив JSON.Затем он объединяет каждый объект json с объектами в БД, изменяет его количество в соответствии с файлом XLS и добавляет метку времени в массив штампов, который содержит изменения в квантичности.

Например:

{"_id":"5c3f531baf4fe3182cf4f1f2",
"sku":123456,
"product_name":"Example",
"product_cost":10,
"product_price":60,
"product_quantity":100,
"Warehouse":4,
"stamps":[]
}

после загрузки XLS, скажем, мы продали 10 единиц, это должно выглядеть так:

{"_id":"5c3f531baf4fe3182cf4f1f2",
"sku":123456,
"product_name":"Example",
"product_cost":10,
"product_price":60,
"product_quantity":90,
"Warehouse":4,
"stamps":[{"1548147562": -10}]
}

Сейчас я не могу найтиправильные команды для mongoDB, я разрабатываю для Node.js и Angular, хотел бы прочитать некоторые идеи.

for (let i = 0; i < products.length; i++) {
 ProductsDatabase.findOneAndUpdate(
      {"_id": products[i]['id']},
      //CHANGE QUANTITY AND ADD A STAMP

...
}

Ответы [ 2 ]

0 голосов
/ 22 января 2019

Вам понадобятся две операции здесь.Первым будет получить массив документов из базы данных, которые совпадают с массивами в массиве JSON.Из списка вы сравниваете ключи 'product_quantity' и, если есть изменения, создаете новый массив объектов с идентификатором продукта и изменением количества.

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

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

Рассмотрите возможность использования метода bulkWrite, который используется в модели.Это принимает массив операций записи и выполняет каждую из них, для которой типичная операция обновления для вашего варианта использования будет иметь следующую структуру

{ updateOne :
    {
    "filter" : <document>,
    "update" : <document>,
    "upsert" : <boolean>,
    "collation": <document>,
    "arrayFilters": [ <filterdocument1>, ... ]
    }
}

Таким образом, ваши операции будут следовать следующему шаблону:

(async () => {

    let bulkOperations = []
    const ids = products.map(({ id }) => id)
    const matchedProducts =  await ProductDatabase.find({ 
        '_id': { '$in': ids }
    }).lean().exec()

    for(let product in products) {
        const [matchedProduct, ...rest] = matchedProducts.filter(p => p._id === product.id)
        const { _id, product_quantity } = matchedProduct
        const changeInQuantity = product.product_quantity - product_quantity

        if (changeInQuantity !== 0) {
            const stamps = { [(new Date()).getTime()] : changeInQuantity }

            bulkOperations.push({
                'updateOne': {
                    'filter': { _id },
                    'update': { 
                        '$inc': { 'product_quantity': changeInQuantity },
                        '$push': { stamps }
                    }
                }
            })
        }
    }

    const bulkResult = await ProductDatabase.bulkWrite(bulkOperations)
    console.log(bulkResult)

})()
0 голосов
/ 22 января 2019

Вы можете использовать mongoose's findOneAndUpdate для обновления существующего значения документа.

"use strict";


const ids = products.map(x => x._id);

let operations = products.map(xlProductData => {

  return ProductsDatabase.find({
    _id: {
      $in: ids
    }
  }).then(products => {

    return products.map(productData => {
      return ProductsDatabase.findOneAndUpdate({
        _id: xlProductData.id // or product._id
      }, {
        sku: xlProductData.sku,
        product_name: xlProductData.product_name,
        product_cost: xlProductData.product_cost,
        product_price: xlProductData.product_price,
        Warehouse: xlProductData.Warehouse,
        product_quantity: productData.product_quantity - xlProductData.product_quantity,

        $push: {
          stamps: {
            [new Date().getTime()]: -1 * xlProductData.product_quantity
          }
        },

        updated_at: new Date()
      }, {
        upsert: false,
        returnNewDocument: true
      });
    });

  });

});

Promise.all(operations).then(() => {
  console.log('All good');
}).catch(err => {
  console.log('err ', err);
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...