简体   繁体   English

ScriptDB:用于快速批量更新记录的自定义ID?

[英]ScriptDB: Custom ID for record for quick bulk updating?

I have a 20,000 record ScriptDB of product information that I would like to have updated with current price/stock info on an ~hourly basis. 我有20,000条记录的ScriptDB产品信息,我希望每隔一个小时用当前的价格/库存信息进行更新。 As it stands I am having trouble designing something that doesn't hit against the execution limit headfirst. 从目前的情况来看,我在设计某些东西时很难遇到执行限制。

Downloaded stockfile is customizeable, currently I have it as JSON, like: 下载的stockfile是可自定义的,目前我将其作为JSON,例如:

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

Currently I do something like: 目前,我正在执行以下操作:

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

I can run through about 2,500 records this way, and save them, before hitting time limits. 在达到时间限制之前,我可以以此方式浏览大约2500条记录并保存它们。

Is there any way I can use the SKU directly as the record ID? 有什么方法可以直接将SKU用作记录ID? Then it would be practically 3 lines of code... 那么实际上是三行代码...

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

If not, any obvious way to increase this efficiency? 如果没有,有什么明显的方法可以提高效率?

Thanks! 谢谢!

If it's the 6 minute runtime limit that you're hitting then just (a) make your job idempotent and (b) run it again and again until your work is done. 如果您要达到6分钟的运行时间限制,则只需(a)使您的工作成为幂等,然后(b)一次又一次运行它,直到完成工作。

To do (a) - you can "remember" what sku you're up to or have them as lineitems in a spreadsheet and add a "done" column. 方法(a)-您可以“记住”您要使用的sku或将其作为电子表格中的Lineitem,然后添加“完成”列。

To do (b), in your main loop, if you're over 5 mins and under 6 mins, you can quit and reschedule the job to run again in 10 mins (or less but you'll need locks then). 要执行(b),在您的主循环中,如果您的时间超过5分钟且少于6分钟,则可以退出并重新安排作业以在10分钟内再次运行(或更少,但是您需要锁)。

Is there any way I can use the SKU directly as the record ID? 有什么方法可以直接将SKU用作记录ID?

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

However, instead of an array of objects, you could store your products in a single object, with the SKU used as an object attribute. 但是,您可以将产品存储在单个对象中,而不必使用对象数组,而将SKU用作对象属性。 You'll still need to loop through the input, but you'll only have 2 calls to the ScriptDB service instead of thousands. 您仍然需要遍历输入,但是只有两次调用ScriptDB服务,而不是数千次调用。

Try this: 尝试这个:

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

Here's a screenshot from the debugger, showing what the "products" object looks like when retrieved from the ScriptDb. 这是调试器的屏幕截图,显示了从ScriptDb中检索到的“产品”对象的外观。 If you could massage your input data a bit, you might be able to get that one-pass write you're dreaming of! 如果您可以稍微调整一下输入数据,则可能能够获得您梦dream以求的一次性写入!

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

Note: I've used price and price_default as you did... but I suspect that's a typo. 注意:我已经像您一样使用过priceprice_default ,但是我怀疑这是一个错字。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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