传统的 B2B 潜在客户发掘通常依赖于购买静态目录或行业名单来确定区域潜力。不过,这些静态地图注点 (POI) 数据集几乎会立即过时。由于这些数据通常缺乏最新的营业状态或精细的地点类型分类,外勤销售团队可能会浪费宝贵的时间去联系已永久停业、分类错误或与理想客户画像不符的商家。
本指南提供了一个工作流,可使用地点数据分析和 Places API 弥补这一差距。通过将当前业务账簿映射到地点 ID,您可以使用 BigQuery 隔离某个区域内尚未纳入客户关系管理 (CRM) 数据库的所有运营业务。本指南介绍了如何构建该排除引擎,以便向外勤代表提供经过验证的高度定位的潜在客户名单。

示例应用
假设一家销售终端 (POS) 提供商计划在纽约市扩大实地销售。通常,该组织会提取一份报告,其中包含每个邮政编码区域的餐饮场所总数。这种方法存在销售代表依赖过时数据(例如已永久停业的地点)或不相关潜在客户(例如没有店面的私人餐饮厨房)的风险。
现在,想象一下使用地点数据分析的现代化方法,该方法利用了 Google 地图的全球规模和经过多个来源验证的最新数据。
地点数据分析支持近 500 个地点类别和 70 多个属性,让您能够根据特定业务类型(例如 scandinavian_restaurant)、营业时间和提供的服务(例如 accepts_credit_cards)精准筛选潜在客户。通过将地点数据分析与内部 CRM 系统进行交叉对比,您可以为销售团队提供一份极具针对性的高潜力、未联系潜在客户名单。
解决方案工作流
本指南提供了一个技术框架,用于创建动态“潜在客户地图”,该地图会自动过滤掉您当前的业务,仅留下全新的、可操作的潜在客户,供您的销售团队跟进。
四步架构
- 定义目标场所类型:将理想客户画像映射到场所类型。
- 确定高潜力区域:在 BigQuery 中执行地点计数函数,生成目标业务的密度热图。
- 将 CRM 数据标准化为地点 ID:通过数据清理流水线处理非结构化 CRM 记录,利用地址验证、地理编码和 Places API 查找现有客户的地点 ID。
- 执行空白排除:在 BigQuery 中将 CRM 地点 ID 与地点数据分析数据进行联接,以动态滤除现有客户并输出全新的潜在客户名单。
前提条件
在开始之前,请确保您具备以下各项:
Google Cloud 项目:
- 启用了结算功能的 Google Cloud 项目。
数据访问:
- BigQuery 中的 地点数据分析订阅。
- 您自己的 CRM 数据集(例如 BigQuery 表),其中包含现有客户的企业名称和地址,用作排除列表。
Google Maps Platform:
- API 密钥。
- 已为您的密钥启用以下 API:
IAM 权限:
- 确保您的用户或服务账号具有以下 IAM 角色,以便执行查询和管理数据集:
角色 ID BigQuery Data Editor roles/bigquery.dataEditorBigQuery User roles/bigquery.user
- 确保您的用户或服务账号具有以下 IAM 角色,以便执行查询和管理数据集:
成本意识:
- 本教程使用 Google Cloud 的收费组件。请注意以下方面可能产生的费用:
- BigQuery:根据查询执行期间使用的计算槽或处理的数据量收费。
- 地点数据分析:根据查询用量收费。
- Google Maps Platform:按 Address Validation API、Geocoding API 和文本搜索 API 的请求次数收费。
- 本教程使用 Google Cloud 的收费组件。请注意以下方面可能产生的费用:
第 1 步:定义目标地点类型
地点数据分析支持近 500 个地点类别和 70 多个属性(例如营业时间、支付方式和营业状态)。不加区分地查询整个数据集效率低下且成本高昂。
作为基础步骤,您可以使用 Gemini 等 LLM 将内部客户资料转换为地点类型,以便在构建地点数据分析查询时使用。这种宏观层面的分类定义可确保您后续的 BigQuery 搜索具有高度针对性,从而减少计算处理开销。
例如,如果您要为销售终端系统设计工作流,可以向 Gemini 提供地点类型列表,并使用以下提示词:
“假设您是一名市场分析师。在受支持的 Google 地图地点类型中,哪些是销售终端系统提供商的主要目标?请说明您做出此决定的理由。”
根据此提示,Gemini 会分析分类,并返回相关地点类型的目标子集,以便在 BigQuery types 过滤条件中使用:
| 主要类别 | 理由 | 关键地点类型 |
|---|---|---|
| 餐饮 | 需要快速的交易处理、桌位管理、订单出票和处理小费。 | restaurant、bar、cafe、coffee_shop |
| 购物 | 需要强大的库存跟踪、条形码扫描、退货处理和会员系统集成功能。 | clothing_store、grocery_store、supermarket、convenience_store |
| 服务和健康与保健 | 需要集成预约、日程安排、客户资料和佣金跟踪功能。 | hair_salon、beauty_salon、spa、massage |
| 休闲、娱乐和体育 | 需要快速处理顾客高峰、数字票务扫描和快速售卖。 | movie_theater、amusement_park、bowling_alley、stadium |
在本指南中,我们将重点介绍餐饮类别的建议地点类型。
第 2 步:提取商家数量以确定高潜力区域
若要找出机会点,您首先需要从宏观角度了解业务密度。为此,您可以在 BigQuery 中执行地点计数函数(例如 PLACES_COUNT_PER_H3 或 PLACES_COUNT_PER_GEO)。
虽然您可以直接查询数据集,但地点计数函数是预定义的、经过优化的 SQL 查询,不会强制执行至少 5 个地点的标准汇总阈值(标准直接查询会忽略包含 1-4 个商家的行;不过,这些函数可让您准确看到即使只有一个潜在客户存在的位置)。至关重要的是,这些函数会使用 sample_place_ids 列返回每个地理区域最多 250 个地点 ID 的数组。这既能为区域规划人员提供统计热图,又能提供潜在客户发掘所需的基础标识符。
以下查询演示了如何使用公共数据集动态检索复杂多边形(纽约市的整个边界),然后将该地理位置传递给地点计数函数。通过在整个城市范围内以更宽的分辨率 (8) 利用 H3 空间索引,您可以生成宏观密度图。
此外,通过选择所有列 (SELECT *),该函数会返回 geography 列,即表示 H3 单元的多边形。这样,您就可以立即将 BigQuery 结果导入商业智能工具(例如 Looker Studio),以创建填充地图可视化图表,直观地揭示市场热点。
-- Illustrative logic: Extracting target business counts per H3 cell across New York City
DECLARE geo GEOGRAPHY;
-- Get the geography for New York City using the Overture Maps public dataset
SET geo = (SELECT geometry FROM `bigquery-public-data.overture_maps.division_area`
WHERE country = 'US' AND subtype = 'locality' AND names.primary = 'New York' LIMIT 1);
SELECT *
FROM `YOUR_PROJECT_NAME.places_insights___us.PLACES_COUNT_PER_H3`(
JSON_OBJECT(
'geography', geo,
'h3_resolution', 8,
'types',['restaurant', 'bar', 'cafe', 'coffee_shop'],
'business_status', ['OPERATIONAL']
)
)
ORDER BY count DESC;

从生成的可视化图表中可以看出,整个曼哈顿都有明显的目标企业高密度区域。在本文档的其余部分,我们将重点关注其中一个高潜力区域:联合广场附近。
第 3 步:将 CRM 数据标准化为地点 ID
如需执行排除分析,您首先需要将 CRM 记录转换为地点 ID。由于 CRM 数据通常是非结构化的,因此将原始文本传递到搜索 API 会导致匹配率较低。使用此两步流水线可清理地址、考虑区域 API 覆盖范围,并确保为 BigQuery 提取正确的场所地点 ID。
假设您的 CRM 中有以下 5 个位于纽约市的餐厅客户:
| 地名 | 地址 |
|---|---|
| Boucherie Union Square | 225 Park Ave S, New York, NY 10003, United States |
| Gramercy Tavern | 42 E 20th St, New York, NY 10003, United States |
| Barn Joo Union Square | 35 Union Square W, New York, NY 10003, United States |
| LOS TACOS No.1 | 200 Park Ave S, New York, NY 10003, United States |
| Union Square Cafe | 101 E 19th St, New York, NY 10003, United States |
由于这些记录由非结构化文本组成,因此您无法在 BigQuery 中直接将它们与地点数据分析数据联接。而是通过以下流水线处理每一行,以标准化文本并提取地点 ID。
第 3a 步:地址清理和直接匹配
请先对地址数据进行标准化处理。根据目标国家/地区选择 API:
对于受支持的国家/地区,请将拼接后的 CRM 商家名称和地址传递到 API 中。检查响应的 result.geocode.placeTypes 数组:
- 商家匹配:如果包含
establishment或point_of_interest,则表示 API 已成功解析商家。将此placeId附加到您的数据集,然后转到下一条 CRM 记录。此条目不需要进一步的 API 调用。 - 非场所匹配:如果地址不包含这些商家类型,则 API 无法明确确认商业实体。返回的地点 ID 表示地貌(例如建筑物、街道或城市)。请勿在 BigQuery 中使用此地点 ID,否则会导致排除联接失败。而是保存
result.address.formattedAddress并继续执行第 3b 步。
方法 2:Geocoding API
对于地址验证功能不支持的地区,请仅将 CRM 地址传递给 Geocoding API。请勿包含商家名称,因为 Geocoding API 可能会返回不可预测的结果。提取生成的 formattedAddress,然后继续执行第 3b 步。
高级架构:使用 LLM 处理非结构化数据
如果您的 CRM 数据质量极差,例如商家名称和地址混杂在单个自由文本备注字段中,请使用 Gemini 等 LLM 预处理记录。您可以提示 Gemini 从位置信息中清晰地解析出商家名称,然后再将其输入到此流水线中。
第 3b 步:解决商业实体问题
如果第 3a 步仅返回清理后的地址,请将其与原始 CRM 商家名称串联,然后传递给 文本搜索 API。首先对地址进行标准化处理,可显著提高匹配率。
为了优化性能和费用,请使用字段掩码 (X-Goog-FieldMask:
places.id) 并设置 "pageSize": 1,以确保仅返回匹配度最高的地点 ID。
文本搜索请求示例:
curl -X POST -d '{
"textQuery" : "Gramercy Tavern 42 E 20th St, New York, NY 10003-1324, USA",
"pageSize": 1
}' \
-H 'Content-Type: application/json' -H 'X-Goog-Api-Key: YOUR_API_KEY' \
-H 'X-Goog-FieldMask: places.id' \
'https://places.googleapis.com/v1/places:searchText'
流水线输出
通过这个两步流水线处理 CRM 记录后,无论是在第 3a 步中成功提取了 ID,还是在第 3b 步中使用文本搜索解析了 ID,您的最终目标都是向数据集附加一个新的 place_id 列。现在,您可以将生成的表作为排除列表上传到 BigQuery。
| 地名 | 地址 | 地点 ID |
|---|---|---|
| Boucherie Union Square | 225 Park Ave S, New York, NY 10003, United States | ChIJc1Vf7KFZwokR1YL2Rn9oxi8 |
| Gramercy Tavern | 42 E 20th St, New York, NY 10003, United States | ChIJvSQIgqFZwokRFYQbJdzceSs |
| Barn Joo Union Square | 35 Union Square W, New York, NY 10003, United States | ChIJQ7XpyqNZwokRQpVfvGEViWM |
| LOS TACOS No.1 | 200 Park Ave S, New York, NY 10003, United States | ChIJFZh0PABZwokRVzoJu0o-mLY |
| Union Square Cafe | 101 E 19th St, New York, NY 10003, United States | ChIJxTHke6JZwokRCLWVd99eDBw |
第 4 步:在 BigQuery 中执行空白排除分析
将现有客户映射到地点 ID 后,使用地点计数函数查找全新潜在客户。
在此示例中,我们将搜索联合广场(40.73595、-73.99043)方圆 850 米范围内正在营业的目标商家(餐厅、酒吧、咖啡馆和咖啡店)。为了获得更精细的街道级路线视图,我们将 PLACES_COUNT_PER_H3 函数的分辨率提高到 10。
由于该函数会将地点 ID 作为数组返回到 sample_place_ids 列中,因此我们必须对该数组执行 UNNEST 操作,以便将每个潜在商家分别放在单独的行中。然后,我们对已知客户地点 ID 执行 LEFT JOIN。
为了证明排除逻辑在此演示中有效,以下查询使用 CASE 语句来标记结果,而不是将其完全过滤掉。它还会明确地将现有客户排序到结果表的最顶部,以便您验证他们是否已成功匹配。
SQL 查询
WITH existing_customers AS (
-- 1. Simulate the uploaded CRM table
SELECT * FROM UNNEST([
'ChIJc1Vf7KFZwokR1YL2Rn9oxi8', -- Boucherie Union Square
'ChIJvSQIgqFZwokRFYQbJdzceSs', -- Gramercy Tavern
'ChIJQ7XpyqNZwokRQpVfvGEViWM', -- Barn Joo Union Square
'ChIJFZh0PABZwokRVzoJu0o-mLY', -- LOS TACOS No.1
'ChIJxTHke6JZwokRCLWVd99eDBw' -- Union Square Cafe
]) AS place_id
),
target_area_businesses AS (
-- 2. Query Places Insights for target businesses in the radius
SELECT
h3_cell_index,
place_id
FROM `places_insights___us.PLACES_COUNT_PER_H3`(
JSON_OBJECT(
'geography', ST_GEOGPOINT(-73.99043, 40.73595),
'geography_radius', 850,
'h3_resolution', 10,
'types',['restaurant', 'bar', 'cafe', 'coffee_shop'],
'business_status', ['OPERATIONAL']
)
),
UNNEST(sample_place_ids) AS place_id
)
-- 3. The "Proof" Output: Flag them instead of filtering them out
SELECT
t.h3_cell_index,
t.place_id,
-- Flag whether the LEFT JOIN found a match in the CRM table
CASE
WHEN e.place_id IS NOT NULL THEN 'Existing Customer (To Be Excluded)'
ELSE 'Net-New Lead'
END AS lead_status,
CONCAT('https://www.google.com/maps/search/?api=1&query=Place&query_place_id=', t.place_id) AS actionable_maps_url
FROM target_area_businesses t
LEFT JOIN existing_customers e
ON t.place_id = e.place_id
ORDER BY
-- Explicitly sort the existing customers to the top (0 comes before 1)
CASE WHEN e.place_id IS NOT NULL THEN 0 ELSE 1 END ASC;
查询结果
以下是查询输出的摘录,展示了如何在同一精细 H3 单元格中成功识别现有客户并将其与全新潜在客户区分开来。
请注意,该查询如何利用 CONCAT 语句,使用 place_id 构建跨平台地图网址。这会自动生成 actionable_maps_url 列,为您的销售团队提供一个可点击的即时链接,以便在 Google 地图移动应用或浏览器中加载确切的商家。
h3_cell_index |
place_id |
lead_status |
actionable_maps_url |
|---|---|---|---|
| 8a2a100d2767fff | ChIJQ7XpyqNZwokRQpVfvGEViWM | 现有客户(待排除) | https://www.google.com/maps/search/?api=1&query=Place&query_place_id=ChIJQ7XpyqNZwokRQpVfvGEViWM |
| 8a2a100d20effff | ChIJvSQIgqFZwokRFYQbJdzceSs | 现有客户(待排除) | https://www.google.com/maps/search/?api=1&query=Place&query_place_id=ChIJvSQIgqFZwokRFYQbJdzceSs |
| 8a2a100d2397fff | ChIJc1Vf7KFZwokR1YL2Rn9oxi8 | 现有客户(待排除) | https://www.google.com/maps/search/?api=1&query=Place&query_place_id=ChIJc1Vf7KFZwokR1YL2Rn9oxi8 |
| 8a2a100d2397fff | ChIJFZh0PABZwokRVzoJu0o-mLY | 现有客户(待排除) | https://www.google.com/maps/search/?api=1&query=Place&query_place_id=ChIJFZh0PABZwokRVzoJu0o-mLY |
| 8a2a100d23b7fff | ChIJxTHke6JZwokRCLWVd99eDBw | 现有客户(待排除) | https://www.google.com/maps/search/?api=1&query=Place&query_place_id=ChIJxTHke6JZwokRCLWVd99eDBw |
| 8a2a1072c96ffff | ChIJ6atD-WRZwokRULgcZ4TWin8 | 全新潜在客户 | https://www.google.com/maps/search/?api=1&query=Place&query_place_id=ChIJ6atD-WRZwokRULgcZ4TWin8 |
| 8a2a1072c96ffff | ChIJ09yg-llZwokRKAgp0jg6TCU | 全新潜在客户 | https://www.google.com/maps/search/?api=1&query=Place&query_place_id=ChIJ09yg-llZwokRKAgp0jg6TCU |
使用 Places UI Kit 直观呈现潜在客户
您可以直接将 place_ids 传递给 Places UI Kit,而不是提供原始地图网址,从而为销售团队构建一个内容丰富的内部潜在客户发掘信息中心。您可以跨平台使用,将预构建的组件放入 Web、Android 和 iOS 中。这些组件会自动显示丰富的地图注点数据,例如照片、评分和营业时间,而无需您编写前端界面代码或手动处理 API 响应。
地点计数数据限制
地点计数函数在 sample_place_ids 数组中每个地理单元格最多返回 250 个地点 ID。如果某个区域非常密集,则该特定单元格生成的潜在客户名单上限为 250。为确保您在高度密集的市场中捕获所有潜在客户,请考虑以下策略:
- 使用具体的查询过滤条件:不要将多种类型组合到一个查询中(如上例所示),而是针对每种地点类型分别运行查询。
- 缩小空间范围:使用较小的
geography_radius缩小整体搜索区域,或通过提高 H3 分辨率(最高可达分辨率 11)将区域划分为更小、更精细的存储桶。 - 根据密度调整分辨率:在分析人口密度不同的区域时,动态调整搜索范围,以避免达到 250 个地点 ID 的上限。在商家分布稀疏的农村地区,使用更宽泛的 H3 分辨率(例如 6 或 7)或更大的
geography_radius。相反,在人口稠密的城市地区,请使用非常精细的分辨率(例如 10 或 11),以确保您能捕获所有潜在客户,而不会截断列表。
生产环境排除查询
验证现有客户已成功识别后,您可以还原为正式版查询。将最终的 SELECT 块替换为以下 WHERE 子句,以永久滤除现有业务:
SELECT
t.h3_cell_index,
t.place_id,
CONCAT('https://www.google.com/maps/search/?api=1&query=Place&query_place_id=', t.place_id) AS actionable_maps_url
FROM target_area_businesses t
LEFT JOIN existing_customers e
ON t.place_id = e.place_id
WHERE e.place_id IS NULL; -- Filters out the CRM matches
架构治理和合规性
为了保持系统的高性能和合规性,请遵循以下标准:
- 将地点 ID 用作永久性标识符:除了地点 ID 之外,Google Maps 服务条款禁止存储或缓存从 Places API 返回的单个地图注点数据(例如电话号码和详细联系信息)。请将地点 ID 用作永久性标识符,以便进行周期性空白分析。
- 通过实时 API 调用确保属性时效性:使用地点 ID 对地点详情 API 进行“即时”调用,确保您的销售人员拥有该地点的最新商家和联系信息。或者,如查询输出中所示,您可以动态构建 Google 地图网址,为销售团队提供指向 Google 地图上的商家资料的直接链接。
总结
通过将地点 ID 标准化为主键,您成功地弥合了宏观市场分析与可操作的基层销售运营之间的差距。此架构可避免传统基于受众群体的定位的不准确性,利用无服务器数据仓储进行繁重的计算联接,并在 API 层严格遵循费用管理和合规性最佳实践。
后续操作
- 请求访问地点数据分析 示例数据集。
- 使用 BigQuery 数据交换列表订阅地点数据分析数据集,以访问示例数据或完整的国家/地区数据。
- 查看过滤条件参数参考文档,根据业务属性和类型微调 BigQuery SQL 查询。
- 在 CRM 或销售路线规划应用中实现动态 Places API 查找,以便为生成的新潜在客户提供最新、合规的详细联系信息。
贡献者
- Henrik Valve | DevX 工程师