我正在探索Google API,主要是Places API。由于对 Google Places API 的请求数量限制为 100,000 个,因此我正在寻找最小化发送到 API 的请求数量的方法。我正在考虑使用数据库来存储以前收到的响应,因此将来我可以在不向 API 发出请求的情况下检索它们,并且只有在之前没有将所需数据存储在我的数据库中的情况下才会向 API 发出请求。
根据 Google API 使用条款,特别是第 10.1.3 节"对复制或数据导出的限制",不允许无限期存储数据,但临时缓存数据是合法的:
您不得预先提取、缓存或存储任何内容,但您可以存储:(i) 有限数量的内容,用于提高您的 Maps API 实施的性能,前提是您暂时这样做(在任何情况下都不会超过 30 个日历日)、安全且不允许在服务之外使用内容;以及 (ii) 地图 API 文档的任何内容标识符或密钥特别允许您存储。例如,您不得使用内容创建"地点"或其他本地列表信息的独立数据库。
我发现这一部分没有得到很好的解释。我可以将 API 接收的任何数据存储在我的数据库中 30 天还是仅存储地点的 ID?因为在其他一些上下文中,我读到只允许存储 id。我是这样理解的:我可以无限期地存储地点 ID,但只能使用整个数据 30 天。
因为我只阅读了几天关于Google API的信息,所以我可能错过了一些使用条款,所以如果你能帮助我,我将不胜感激。
任何关于如何最大限度地减少对 API 的调用次数的建议,或分享一些与使用这些 API 的实际项目相关的经验,将不胜感激。另外,如果您能向我建议一些可以提供类似功能的替代 API,那将非常有帮助。
提前谢谢你!
根据我对Google Places API的经验,您的理解几乎是正确的。让我用我自己的话来解释这两个规定:
i) 如果不预取或重新分发到应用程序外部,您可以将 API 结果缓存长达 30 天。
ii) 您可以在应用特定数据中使用地点 ID 或关键字,但不能使用其他内容(例如,如果您的应用允许用户"签到"地点,则可以在用户对象上存储地点 ID 列表,并根据需要按 ID 查找地点,但您无法存储包含 Google 名称/详细信息的所有地点的列表)。
为了减少 API 调用次数并加速我的应用程序,我所做的是将附近的 place 调用缓存在一个简单的键值缓存中,其中键是四舍五入到一定精度的 lat-lng 对(以便一定半径内的调用将命中缓存),值是整个 JSON 结果字符串。这是我的代码,它是在谷歌的App Engine上运行的Java:
// Using 4 decimal places for rounding represents approximately 11 meters of precision
// http://gis.stackexchange.com/questions/8650/how-to-measure-the-accuracy-of-latitude-and-longitude
public static final int LAT_LONG_CACHE_PRECISION = 4;
public static final int CACHE_DURATION_SEC = 24 * 60 * 60; // one day in seconds
...
String cacheKey = "lat,lng:" + round(latitude) + "," + round(longitude);
asyncCache.put(cacheKey, dataJSON, Expiration.byDeltaSeconds(CACHE_DURATION_SEC), MemcacheService.SetPolicy.SET_ALWAYS);
...
private static double round(double value) {
BigDecimal bd = new BigDecimal(value);
bd = bd.setScale(LAT_LONG_CACHE_PRECISION, RoundingMode.HALF_UP);
return bd.doubleValue();
}
至于替代API,我建议您查看以下内容:
Yelp API - 提供谷歌缺乏的酒吧/餐厅数据
FacebookAPI - 如果您已经在使用Facebook的SDK,则易于使用
事实:地方人行横道 - 聚合和规范化来自许多来源的地点数据,包括Facebook和Yelp,但不包括谷歌
目前我只使用Google Places API,但我计划稍后添加Yelp或Factual以改善最终用户的结果。