Resolve 20,000 messy Healthcare Provider (HCP) records against a 5,000-row golden registry using Snowflake's CORTEX_SEARCH_BATCH function — no ML training, no infrastructure, pure SQL.
Provider / prescriber data arrives from multiple vendor systems (call reports, claims feeds, sample management, speaker programs, congress attendees), each with:
- Inconsistent naming ("Rob Smith" vs "Robert A. Smith, MD")
- Abbreviated specialties ("Hem/Onc" vs "Hematology/Oncology")
- Shortened affiliations ("MGH" vs "Massachusetts General Hospital")
- Missing fields, typos, and mixed formats
Traditional entity resolution requires complex rule-based matching or a dedicated MDM platform. This demo shows how Snowflake's Cortex Search solves it with semantic embeddings in a single SQL statement.
Representative numbers from one sample run (results vary slightly by run and seed):
| Metric | Value |
|---|---|
| Overall accuracy | ~99.6% (19,918 / 20,000 correct in top-1) |
| High confidence (>=0.8) | ~4,800 records, 100% accuracy |
| Medium confidence (0.5-0.8) | ~15,000 records, ~99.6% accuracy |
| Low confidence (<0.5) | small tail (~160 records) — route to human review |
| State-blocked cascading pass | ~99.9% accuracy on records with a known state |
| Batch runtime | ~12 seconds for 20,000 records |
| Infrastructure | Zero (runs entirely in Snowflake) |
Golden HCP Registry (5K) ──> Cortex Search Service (semantic index)
│
Dirty Incoming Records (20K) ──> CORTEX_SEARCH_BATCH ──> Matched Results + Confidence Scores
- Index: A Cortex Search Service embeds the golden registry using
snowflake-arctic-embed-m-v1.5 - Match:
CORTEX_SEARCH_BATCHruns all 20K queries in parallel via a LATERAL join - Score:
METADATA$RESULT_DETAILprovides cosine similarity scores for confidence tiering - Block: The
filterparameter constrains matches by state for higher precision
| File | Description |
|---|---|
cortex_search_hcp_entity_resolution.ipynb |
Main demo notebook (runs in Snowflake Workspaces with Container Runtime) |
setup_infrastructure.sql |
One-time infrastructure setup (compute pool, database, schema, stage, notebook object) + cleanup block |
snowflake.yml |
Project definition for snow notebook deploy |
requirements.txt |
Python dependency (faker) used by the notebook |
All data is generated at runtime inside the notebook — nothing is checked into the repo.
- Names, cities, and ZIP codes are generated with Faker (
fake.first_name(),fake.last_name(),fake.city(),fake.zipcode_in_state()), seeded for reproducibility. - Medical specialties and credentials come from a small curated taxonomy (Faker has no medical-specialty provider).
- Affiliations are real, well-known public health systems, used purely so that abbreviation matching (
MGH->Massachusetts General Hospital) is recognizable. All provider names attached to them are fake.
Everything is deterministic given the fixed seeds (random, numpy, and Faker are all seeded with 42).
- Snowflake account (any edition, AWS/Azure/GCP)
- A warehouse (default:
COMPUTE_WH— change theWAREHOUSEvariable in the notebook config cell if yours differs) SNOWFLAKE.CORTEX_USERdatabase role granted to your role- A compute pool for Container Runtime (created by
setup_infrastructure.sql) faker(installed automatically by the notebook's first cell)
- Run
setup_infrastructure.sqlto create the compute pool, database, schema, stage, and notebook object. - Upload the notebook to a Snowflake Workspace (or deploy with
snow notebook deploy). - Connect the notebook to the compute pool with
SYSTEM$BASIC_RUNTIME. - (Optional) Edit the
DATABASE,SCHEMA, andWAREHOUSEvariables in the config cell to match your environment. - Run all cells top-to-bottom.
The notebook is fully self-contained — it installs Faker, generates all synthetic data, creates the search service, runs batch matching, and analyzes results.
- CORTEX_SEARCH_BATCH: High-throughput batch matching via LATERAL join
- Blocking rules:
filterparameter constrains the search space (e.g., match only within the same state) - Confidence scoring:
METADATA$RESULT_DETAILcosine similarity for auto-accept vs human-review routing - Cascading strategy: Multi-pass matching (strict blocking first, then relaxed)
- Production pattern: Stream + Task for continuous incremental resolution
When you're done, uncomment and run the cleanup block at the bottom of setup_infrastructure.sql to drop the search service, notebook, tables, stage, schema, and compute pool.
- Cortex Search Overview
- Batch Cortex Search
- CREATE CORTEX SEARCH SERVICE
- Snowflake Notebooks in Workspaces
MIT — see LICENSE.