Knowhere
Docs Sign in

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

  1. Category words ("restaurant", "museum", "park") map to a category key — amenity, leisure, tourism, shop. knowhere://docs/categories says which key holds which concept.
  2. Place words map to (area=…), snake_case and lower-case. Unsure, or ambiguous ("Denver" with no state)? Call list_areas. Never invent a name.
  3. Brand words map to name=~ (contains), or brand= when the user clearly means the chain. Chain vs. independent is [brand] vs. [!brand], never a name regex — see knowhere://docs/schema.
  4. Unsure of a value? tag_values(area, key) before filtering, not a guess. tag_keys(area) if unsure the key exists.
  5. "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 the near tool.
  6. Anything about walking goes to walk_reach, never near or (around=…). See knowhere://docs/routing.
  7. 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/categories has units and coverage.
  8. 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=~Costco also 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, or count_only first.
  • =~ 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], not nw[cuisine=~coffee] alone — and prefer = when the value is a known category.