【问题标题】:JSON String to Array to Cache - Improve EfficiencyJSON 字符串到数组到缓存 - 提高效率
【发布时间】:2013-08-08 16:56:57
【问题描述】:

我哭了,终于让这个脚本工作了(谷歌应用程序脚本和 json 的新手,对 javascript 比较熟悉)。它适用于小型数据集,但一旦我跳转到包含 20,000 个项目的大型数据集,它就会超时!我想不出另一种方法来提高效率。这些价格每 3 分钟更新一次,因此我只想将其缓存 10 分钟。我觉得 ScriptDb 不适合这个。本质上,我必须将信息存储在缓存中,因为我使用简单的非缓存版本 testing() 有大约 500 个方程,而 google/api 不允许那么多调用。我想一通电话,从缓存中拉出约 500 次会更好。有没有什么方法可以提高我没有想到的效率?

每 10 分钟运行一次以存储信息。此片段超时。

function updateCache() {
  var cache = CacheService.getPublicCache();
    var myUrl = "http://www.gw2spidy.com/api/v0.9/json/all-items/all"
    var jsonData = UrlFetchApp.fetch(myUrl);
    var jsonArray = JSON.parse(jsonData).results;
      for (var i =0; i < jsonArray.length; i++) {
      cache.put(jsonArray[i].data_id + 'sell', jsonArray[i].min_sale_unit_price, 1500);
      }
    return cache.get(itemID + 'sell')
    }

这是使用缓存并返回数据的函数。

function testing(itemID) {
  var cache = CacheService.getPublicCache();
return cache.get(itemID + 'sell')
}

更新 我更新了代码以使用分页。请参阅 Jon 评论中的后续问题。

//these are all four of the selling functions, cache for 35 min, run every 30 min
function updateSellCacheQ1() {
  var cache = CacheService.getPublicCache();
   for (var page = 0; page < 56; page++) {
   Logger.log('Sell Page #' + page);
   var myUrl = 'http://www.gw2spidy.com/api/v0.9/json/items/all/' + page
    var jsonData = UrlFetchApp.fetch(myUrl);
    var jsonArray = JSON.parse(jsonData).results;
      for (var i = 0; i < jsonArray.length; i++) {
      cache.put(jsonArray[i].data_id + 'sell', jsonArray[i].min_sale_unit_price, 2100);
      }
    }
   }

【问题讨论】:

    标签: arrays json google-apps-script


    【解决方案1】:

    您可以有一个例程(10 分钟计时器)来下载数据并将其作为纯文本文件转储到 Google 云端硬盘中。

    第二个计时器函数(每 2 分钟一次,或者任何不会触发单个执行失败的函数)然后可以将该平面文件的块处理到缓存/scriptDb 中

    因此,如果您有一个 2 分钟的计时器来缓存 20% 的平面文件,则任何召回条目最多会过期 13 分钟,最少会过期 2 分钟。


    或者,您不能根据项目列表查询 api 吗?所以一次更频繁地查询和缓存较小的块?计时器上的每个查询可以是顺序的,也可以是可用项目类别的随机选择?

    更新

    https://github.com/rubensayshi/gw2spidy/wiki/API-v0.9#wiki-item-list

    因此,如果您在查询中使用 /items/all/{page} 选项,您可以计算出在一次执行中可以安全地进行、检索和存储多少个查询。假设是 10。

    var lastPageChecked = ScriptProperties.getProperty('lastPage') + 1,
        checkEnd = lastPageChecked + 10,
        myUrl,
        jsonData,
        jsonArray,
        page;
    
    for (page = lastPageChecked; page < checkEnd; page += 1) {
    
      myUrl = "http://www.gw2spidy.com/api/v0.9/json/items/all/" + page;
      jsonData = UrlFetchApp.fetch(myUrl);
      jsonArray = Utilities.jsonParse(jsonData);
    
      if (page <= json.last_page) {
    
        // [snip] process however you like
    
      } else {
        page = 0;
        break;
      }
    }
    
    ScriptProperties.setProperty('last_page_checked', page);
    

    尽可能频繁地运行该函数,以这种方式格式化的每个查询都会被 api 缓存 15 分钟,因此您有 15 分钟的时间进行剩余的 20 个页面调用。显然,如果您可以在一次执行中进行 20 次调用(2000 个对象),那么您只需要运行脚本 10 次 - 每分钟一次,您就有了空闲时间:D

    警告 - 我已经在 stackoverflow 的编辑器中编写了它,但没有对其进行测试。

    显然,如果你运行:

    "http://www.gw2spidy.com/api/v0.9/json/items/0/" + page 
    

    所有盔甲,比如说,每种类型的盔甲都一样,你会运行更多的触发器,但理论上每个类别都可能更“当前”

    【讨论】:

    • 不幸的是,很难分解这些块。其中一个数据块是 10,000 项大。您对使用缓存或 scriptDb 有意见吗?
    • 刚刚检查过 - 是的,有很多项目 :D 但 api 允许分页,所以这也有帮助吗?
    • 我真的不知道分页是什么。去谷歌!我正在访问类似 22k 项的 API,并在大约 500 个单独的公式中使用数据。我怀疑随着我们发现更多用途,它会增长。我完全理解为什么我要达到这些数字的极限,哈哈。
    • 如果有帮助的话,这里是一个指向 API 的链接。 github.com/rubensayshi/gw2spidy/wiki/API-v0.9
    • 我已经修改了解释分页的答案
    猜你喜欢
    • 2021-01-23
    • 2017-03-02
    • 2018-09-08
    • 1970-01-01
    • 2012-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多