Как многократно вставлять документы в MongoDb со специальным условием - PullRequest
0 голосов
/ 22 сентября 2019

Мне нужно в MongoDB многократное вставлять / обновлять price_lastupdate и stock_lastupdate, только когда цена или запас изменились.

важный думает:

  • возможно вставить новый товар (код +stock_id уникален)
  • обновление price_lastupdate только когда цена была изменена тогда до
  • обновление stock_lastupdate только когда акция была изменена тогда до
  • множественная вставка или обновление, потому что мне нужно слишком много производительности
  • код и stock_id уникально

входные данные:

productList = [
    {
      "code": "123",
      "stock_id": "CZ01",
      "price": 11.2,
      "stock": 10
    },
    {
      "code": "124",
      "stock_id": "CZ02",
      "price": 12.9,
      "stock": 9
    },
    {
      "code": "135",
      "stock_id": "CZ01",
      "price": 9.9,
      "stock": 11
    },
    {
      "code": "110",
      "stock_id": "CZ02",
      "price": 1.7,
      "stock": 5
    },
  ];

целевая структура (код + идентификатор_класса уникальны):

{
    "code": "<string>",
    "stock_id": "<string>",
    "price": <double>,
    "price_lastupdate": <date>,
    "stock": <int>,
    "stock_lastupdate":<date>
}

Ответы [ 2 ]

0 голосов
/ 24 сентября 2019

Я работаю с MongoAtlas.Я решил обновить priceLastUpdate с триггером (тип_операции: обновление, указание события: true, полный_документ: false).

функция триггера:

 exports = function(changeEvent){
  if(changeEvent.updateDescription.updatedFields.price !== undefined){
    context.services.get("xxx").db("xxx").collection("product_items")
      .findOneAndUpdate({
        _id: changeEvent.documentKey._id
      },
      {
        $set:{
          price_lastupdate: new Date()     
        }
      }
    );
  }
};

, но моя проблема с множественной вставкой или многократным обновлением до сих пор не решена.Когда я вставляю / обновляю 350 элементов в 350 циклах с помощью findOneAndModify , время выполнения составляет около 18 секунд.Это недопустимо 10000+ элементов.

Моя текущая служба HTTP:

exports = function(payload, response) {

    const {data} = payload.query;
    const productPrices = JSON.parse(data);
    let products = context.services.get("xxx").db("xxx").collection("product_items");

    productPrices.forEach(oneProductPrice => {
      context.functions.execute("setProductPrice", oneProductPrice);
    });

    return  "OK";
};

Моя текущая функция setProductPrice (вызывается из HTTPСервис):

exports = function(product){

   let products = context.services.get("xxx").db("xxx").collection("product_items");

   products.findOneAndUpdate({
      code: product.code,
      stock_id: product.stock_id
   },
   {
      $set:{
          price: product.price,
      },
      $setOnInsert:{
          code: product.code,
          stock_id:product.stock_id,
          price_lastupdate: new Date()
      }
   },
   {
      upsert: true,
   });
};

Я искал массовая вставка / обновление :

var bulk = db.items.initializeUnorderedBulkOp();
....

, но Mongo Atlas не знает эту функцию.

Есть идеи?

0 голосов
/ 22 сентября 2019

Фон:

Модель данных:

Коллекционные запасы:

{
   _id: "CZ01"
   stock_provider: "ABC",
   supplier_id:"SUP1"

}

Коллекция product_items:

{
    "code": "<string>",
    "stock_id": "CZ01",
    "price": <double>,
    "price_lastupdate": <date>,
    "stock": <int>,
    "stock_lastupdate":<date>
}

Запросы :

  • можно вставить новый товар (код + уникальный идентификатор_клада): Создать составной уникальный индекс на code and stock_id для сохранения уникальности в коллекции product_items
  • update_lastupdate только при изменении цены, чем раньше: создайте поток изменений для просмотра обновлений на product_items.price для обновления значенияproduct.price_lastupdate. Вот пример :

    const mongo = require("mongodb").MongoClient; mongo.connect("mongodb://localhost:27017/?replicaSet=rs0").then(client => { console.log("Connected to MongoDB server"); // Select DB and Collection const db = client.db("mydb"); const collection = db.collection("product_items"); pipeline = [ { $match: { "fullDocument.price": { $gte: 250 } } } ]; // Define change stream const changeStream = collection.watch(pipeline); // start listen to changes changeStream.on("change", function(event) { collection.update({_id:fullDocument}, {$set:{fullDocument.price_lastupdate:fullDocument.price}}) }); });

  • обновлять stock_lastupdate только при изменении запаса, чем раньше: аналогичный поток изменений можно создать для stock_lastupdate.
  • многократная вставка или обновление, потому что мне нужна слишком высокая производительность: вместо вставки / обновления элементов продукта внутри большого массива эта модель данных обеспечивает гибкость вставки, так как это приведет к вставке отдельных документов внутри product_itemscollection.
  • code и stock_id уникальны: позаботились о первой части запросов, создав уникальный индекс для code and stock_id
...