Disclosure: text and example prepared with AI assistance. The example below is synthetic; it is not a production data export.

A local-search dataset has at least two useful units: appearances within a query and unique business identities across queries. Mixing them changes the denominator before the analysis starts. In MapaLocal’s restaurant study, eight Google Maps searches produced 160 appearances and 114 identities. This tutorial shows a small way to preserve that distinction in JavaScript.

Preserve the observation key

The input contract requires a query ID and a stable business ID. Keep the source rank, timestamp and search location alongside them. Deduplicate repeated ingestion of the same observation, not genuine appearances in different queries.

const observations = [ { query: "city", id: "a", rank: 1, url: null }, { query: "city", id: "b", rank: 2, url: "https://example.org" }, { query: "nearby", id: "a", rank: 3, url: null } ]; function summarize(rows) { const seen = new Set(); const clean = []; for (const row of rows) { if (!row.query || !row.id) throw new Error("Missing identity"); const key = JSON.stringify([row.query, row.id]); if (!seen.has(key)) { seen.add(key); clean.push(row); } } return { appearances: clean.length, identities: new Set(clean.map(r => r.id)).size, missingUrlFields: clean.filter(r => r.url == null || r.url.trim() === "").length }; } console.log(summarize(observations)); // { appearances: 3, identities: 2, missingUrlFields: 2 } 

This assumes one snapshot and one appearance per identity per query. For repeated snapshots, include snapshot ID in the key. Identity reconciliation between place IDs and CIDs belongs upstream; do not silently substitute display names. The example does not validate URL ownership or crawl websites.

Missing is not negative evidence

missingUrlFields means the source did not provide a usable field. It does not mean the restaurant has no website. In the real study, 56 of 160 appearances lacked a URL; 40 of 114 identities lacked one across all their appearances. Those statements have different denominators and neither proves website absence.

Keep rank and groups intact

If you exclude an ambiguous category, preserve the original rank rather than moving later results upward. Otherwise your Top 3 can silently become a different group. The restaurant study kept main and strict datasets separate, with 160/114 and 159/113 appearances/identities respectively.

What the code cannot establish

These counts are bookkeeping. They do not explain why a result ranks, estimate all businesses in a city or measure conversions. In the eight real queries, review-count medians for the Top 3 were higher in four and lower in four than positions 4–20. Preserve query, location and time before drawing any broader conclusion.

The research and its charts are published in Spanish. This technical adaptation focuses on the data contract rather than reproducing the full article.