我正在最终确定Data Studio连接器并注意到API调用次数的一些奇怪行为。
我期待看到一个API调用,我看到多个调用。
在我的应用程序脚本中,我保留了一个简单的计数器,每次获取url都会增加1,这就是我希望用getData()看到正确的数字。
但是,在我的API监控日志中(使用Runscope),我看到同一个端点有多个API请求,并且单个getData()调用中不同端点的数量不同(它们应该都是相同的)。 E.g。
我无法在此处发布代码(客户端项目),但它与Google文档中的数据连接器代码基本相同。我实施了缓存和退避。
寻找任何想法或者是否有人经历过类似的事情?
由于
答案 0 :(得分:1)
根据 this reference,如果您没有为字段明确定义此属性,GDS 还将执行语义类型检测。如果查询是语义类型检测,则请求将具有 sampleExtraction: true
当 Data Studio 执行社区连接器的 getData 函数以进行语义检测时,传入的请求将包含一个将设置为 true 的 sampleExtraction 属性。
答案 1 :(得分:0)
如果GDS报告包含多个具有不同维度/指标配置的小部件,则GDS可能会针对每个小部件触发多个getData
调用。
答案 2 :(得分:0)
有一个较晚的答案,但这可能会帮助面临相同问题的其他人。
连接到图形的窗口小部件/搜索过滤器发出自己的getData调用。如果您的自定义适配器是为通过第三方服务通过API调用检索数据而创建的,而GDS向前发送的与request.fields属性无关的数据=>,则这些API调用将乘以N + 1(其中N =窗口小部件/您的报告正在实施的搜索过滤器。
我也没有找到官方的解决方案,所以我发明了一种使用缓存的解决方法。
该图对getData的请求(通常请求的字段多于搜索过滤器)将是唯一允许查询API端点的请求。在开始这样做之前,它将在缓存“ cache_ {hashOfReportParameters} _building” => true中存储密钥。
if (enableCache) {
cache.putString("cache_{hashOfReportParameters}_building", 'true');
Logger.log("Cache is being built...");
}
它将检索API响应,进行分页,并缓冲结果。
完成后,它将删除缓存键“ cache_ {hashOfReportParameters} building”,并将最终缓存的最终合并结果缓存在“ cache {hashOfReportParameters} _final”内部。
在过滤器方面,它们还会调用:getData,但通常最多只能包含3个请求的字段。我们要做的第一件事是确保它们不能在主getData调用之前开始执行...因此,对于可能是同一数据集之后的搜索过滤器/小部件,我们会增加一些延迟:< / p>
if (enableCache) {
var countRequestedFields = requestedFields.asArray().length;
Logger.log("Total Requested fields: " + countRequestedFields);
if (countRequestedFields <= 3) {
Logger.log('This seams to be a search filters.');
Utilities.sleep(1000);
}
}
此后,我们在报告的所有移动部分(日期范围以及您设置的可能影响从API端点检索的数据的所有其他参数)上计算哈希值:
现在最好的部分是,只要主图仍在构建缓存,我们就使这些getData调用等待:
while (cache.getString('cache_{hashOfReportParameters}_building') === 'true') {
Logger.log('A similar request is already executing, please wait...');
Utilities.sleep(2000);
}
在此循环之后,我们尝试检索“ cache_ {hashOfReportParameters} _final”的内容-万一失败,最好有一个备份计划-这将是允许它再次遍历API 。我们在检索缓存的数据时遇到了2%的错误率...
使用缓存的结果(或缓冲的API响应),您只需按照GDS所需的架构(在图形和过滤器之间有所不同)转换响应即可。
开始实施此操作时,您会注意到另一个问题……Google缓存每个密钥的最大大小限制为100KB。但是,您可以缓存的密钥数量没有限制...而且幸运的是,过去其他人也遇到过类似的需求,并且提出了一个聪明的解决方案,将需要缓存的一大块分割成多个缓存密钥,然后粘合在需要检索时将它们重新组合为一个对象。
我无法与您分享我们已实施的最终解决方案,因为它太过具体于客户-但我希望这至少可以给您一个解决问题的好方法。
缓存完整的API结果通常是一个好主意,如果近乎实时足以满足您的需求,则可以避免不必要的往返行程和服务器负载。