Natural Language to Queries
For translating user intent into Knowhere queries: the patterns that come up most, and the rules for choosing among them.
Rules
- Category words ("restaurant", "museum", "park") map to a category key —
amenity,leisure,tourism,shop.knowhere://docs/categoriessays which key holds which concept. - Place words map to
(area=…),snake_caseand lower-case. Unsure, or ambiguous ("Denver" with no state)? Calllist_areas. Never invent a name. - Brand words map to
name=~(contains), orbrand=when the user clearly means the chain. Chain vs. independent is[brand]vs.[!brand], never a name regex — seeknowhere://docs/schema. - Unsure of a value?
tag_values(area, key)before filtering, not a guess.tag_keys(area)if unsure the key exists. - "near a point" with real coordinates is
(around=radiusMetres,lat,lon)(5 mi ≈8047). Without coordinates ("near downtown") it is too fuzzy for a filter — use(area=…)alone. For "A near a set of B", use theneartool. - Anything about walking goes to
walk_reach, nevernearor(around=…). Seeknowhere://docs/routing. - Climate, hazard, and environment words are tags, not general knowledge.
"dry", "mild winters", "sunny", "muggy", "growing zone", "floodplain",
"wildfire risk", "radon", "air quality", "quiet" all map to keys this build
stamps on every US entry —
climate:*,fema:*,usfs:*,nri:*,fire:*,usgs:radon_potential,epa:aqi_*,bts:noise. They are not OpenStreetMap tags, so nothing you know about OSM predicts them. Never substitute your own recollection of a region's climate for a value the database holds;knowhere://docs/categorieshas units and coverage. - Favour recall when the user is exploring. If several values could
satisfy the intent, prefer the OR form (
[amenity=cafe,restaurant]) over one narrow guess.
Mappings
| Ask | Query |
|---|---|
| "restaurants in California" | nw[amenity=restaurant](area=california) |
| "Starbucks in Seattle" | nw[name=~Starbucks](area=seattle) |
| "the Starbucks chain" | nw[brand=Starbucks](area=seattle) |
| "independent coffee shops in Bozeman" | nw[amenity=cafe][!brand](area=bozeman) |
| "cafes or restaurants in Denver" | nw[amenity=cafe,restaurant](area=denver) |
| "restaurants in LA that aren't McDonald's" | nw[amenity=restaurant][name!~McDonald](area=los_angeles) |
| "cities in Texas over 100,000 people" | n[place=city][population>100000](area=texas) |
| "universities in Massachusetts with a name" | wr[amenity=university][name](area=massachusetts) |
| "sushi restaurants in San Francisco" | nw[amenity=restaurant][cuisine=~sushi](area=san_francisco) |
| "parks without a name in Portland" | nw[leisure=park][!name](area=portland) |
| "museums between -122.5,37.7 and -122.4,37.8" | nw[tourism=museum](area=san_francisco)(bb=-122.5,37.7,-122.4,37.8) |
| "boundaries in Colorado named Denver" | *[boundary=administrative][name=~Denver](area=colorado) |
| "dry with mild winters, in Arizona" | n[place=town,city][climate:precip_annual<16][climate:low_jan>30](area=arizona) |
| "towns out of the floodplain in Texas" | n[place=town][fema:sfha=no](area=texas) |
| "low wildfire risk in Colorado" | n[place=town][usfs:wildfire_hazard=very_low,low](area=colorado) |
Travel questions are not queries
"What's within a 15-minute walk?", "is this house walkable to a coffee
shop?", "any parks I can walk to?" — walk_reach, with find carrying the
query:
walk_reach area=colorado from_lat=39.7392 from_lon=-104.9847
max_walk_meters=1250
find="nw[amenity=cafe](area=colorado)"
Report no_walkable_network: true as "the area has no pedestrian paths", not
as "nothing nearby" — one is a fact about sidewalks, the other a verdict on
the neighbourhood.
"How far is the nearest Costco by car?" — search for candidates, then
drive_times to rank them. There is no driving reachability tool; you must
name the destinations.
"I want to walk two miles in a loop" — walk_loop, with the length as
target_meters or the time as target_minutes ("walk for an hour" is
target_minutes=60). "A mile loop that sees all the parks" adds
passing with the query for what to see:
walk_loop area=colorado from_lat=39.7392 from_lon=-104.9847
target_meters=1609 passing="nw[leisure=park](area=colorado)"
Report the length each loop actually came out at (meters), never the
length that was asked for. A result with none set is a real answer —
quote its reason rather than retrying; a cul-de-sac subdivision genuinely
has no two-mile loop.
The limits behind all three — snapping, area boundaries, walking caps — are in
knowhere://docs/routing.
Pitfalls
- Don't forget
(area=…). Every query needs one. - Don't map "near Seattle" to a bounding box without real coordinates.
=~is contains, not regex — no anchors, no wildcards.- Chain searches return more than the stores.
name=~Costcoalso matches its gas station, pharmacy, and per-aisle nodes. Filter by the primary feature tag as well. - Broad and unfiltered is slow. A bare category over a large area can time
out. Narrow with a
(bb=…)— the cheapest, since it prunes on the spatial cell index — a second tag filter, orcount_onlyfirst. =~is only indexed on the name-ish tags (name,name:<lang>,alt_name,brand,operator). Contains on any other tag is a scan: correct, but it reads every row the other filters left. Pair it with something selective —nw[amenity=cafe][cuisine=~coffee], notnw[cuisine=~coffee]alone — and prefer=when the value is a known category.
Related
knowhere://docs/query— syntax reference.knowhere://docs/categories— concept to tag key.knowhere://docs/errors— codes when a translation misses.