0

我有 20,000 条记录 ScriptDB 的产品信息,我希望每小时更新一次当前的价格/库存信息。就目前而言,我在设计一些不首先达到执行限制的东西时遇到了麻烦。

下载的 stockfile 是可定制的,目前我有它作为 JSON,如:

[
{"sku":"MYSKU1","price":14.99,"qty":2},
{"sku":"MYSKU2","price":22.99,"qty":25},
{"sku":"MYSKU3","price":91.99,"qty":31}
]

目前我做类似的事情:

var prod_feed = UrlFetchApp.fetch("https://www.site.com/myJSONfile").getContentText();
var prod_data = JSON.parse(prod_feed);
var prod_qty = 0, i = 0;
var prod_code = "";
var prod_price = "";

var db = ScriptDb.getMyDb();
var result_array = [];
var result_current = {};
var time_obj = dbDateObject();

for(i = 0; i < prod_data.length; i++) {

    var result = db.query({sku: prod_data[i]["sku"]}).next(); // result will be null if no match

    if (!result) {
    // No match, create new object with this SKU for insertion
      result = {};
      result["sku"] = prod_data[i]["sku"];
    }

    result["qty"] = prod_data[i]["qty"];
    result["price_default"] = prod_data[i]["price"];
    result["last_product_update"] = time_obj;
    result_array[i] = result;

}

var results = db.saveBatch(result_array, false);

我可以通过这种方式浏览大约 2,500 条记录,并在达到时间限制之前保存它们。

有什么办法可以直接使用 SKU 作为记录 ID?然后它实际上将是 3 行代码......

var prod_feed = UrlFetchApp.fetch("https://www.site.com/myJSONfile").getContentText();
var prod_data = JSON.parse(prod_feed);
var results = db.saveBatch(prod_data, false);

如果没有,有什么明显的方法可以提高这种效率吗?

谢谢!

4

2 回答 2

2

有什么办法可以直接使用 SKU 作为记录 ID?

可悲的是没有。Every ScriptDb object has an id, assigned by the system when it is stored, which is an opaque, immutable string value.ScriptDb 文档。)

但是,您可以将产品存储在单个对象中,而不是对象数组,并将 SKU 用作对象属性。您仍然需要遍历输入,但您将只有 2 次调用 ScriptDB 服务,而不是数千次。

尝试这个:

  var prod_feed = UrlFetchApp.fetch("https://www.site.com/myJSONfile").getContentText();
  var prod_data = JSON.parse(prod_feed);

  var db = ScriptDb.getMyDb();
  var result = db.query({type: "products"});
  var products = {};
  if (result.hasNext()) {
    // Projects database object already exists
    products = result.next();
  }
  else {
    // Not found, so create the Projects database object.
    var product_data = new Object();
    products = {type: "products", data: product_data};
  }

  var time_obj = dbDateObject();

  for (var i = 0; i < prod_data.length; i++) {

    if (!(prod_data[i]["sku"] in products.data)) {
      // No match, create new object with this SKU for insertion
      products.data[prod_data[i]["sku"]] = {};
    }

    // Update info for this item
    var item = products.data[prod_data[i]["sku"]];
    item.qty = prod_data[i].qty;
    item.price_default = prod_data[i].price;
    item.last_product_update = time_obj;
  }

  var results = db.save(products);

这是调试器的屏幕截图,显示了从 ScriptDb 检索时“产品”对象的外观。如果您可以稍微修改一下您的输入数据,您可能会获得您梦寐以求的一次性写入!

“产品”对象的调试器屏幕截图

笔记:我用过price,和price_default你一样……但我怀疑这是一个错字。

于 2013-01-17T15:23:51.640 回答
2

如果您达到了 6 分钟的运行时间限制,那么只需 (a) 使您的工作具有幂等性,并且 (b) 一次又一次地运行它,直到您的工作完成。

要做 (a) - 您可以“记住”您正在处理的 sku 或将它们作为电子表格中的 lineitems 并添加“完成”列。

要执行 (b),在您的主循环中,如果您超过 5 分钟且不到 6 分钟,您可以退出并重新安排作业以在 10 分钟内再次运行(或更短,但那时您需要锁定)。

于 2013-01-17T04:16:14.930 回答