Summary
In this post, I'm going demonstrate a real-world usage scenario of one of the features of Redis Search: Suggestion (aka autocomplete). This particular autocomplete scenario is around addresses, similar to what you see in Google Maps. I pull real address data from a Canadian government statistics site and populate Redis suggestion dictionaries for autocomplete of either full address (with a street number) or just street name. The subsequent address chosen by the user is then put into a full Redis search for an exact match.
Architecture
Application
I wrote this app completely in Javascript: front and back end.
Front End
The front end is a static web page with a single text input. The expected input is either a street name or house number + street name. The page leverages this Javascript autocomplete input module. The module generates REST calls to the back end. Screenshot below:
Back End
The back end consists of two Nodejs files: dataLoader.js and app.js. The dataLoader module handles fetching data from the Canadian gov site and loading it into Redis as JSON objects. Additionally, it sets up two suggestion dictionaries: one that includes the street number with the address and another that does not. Snippet below of the Redis client actions.
async #insert(client, doc) { await client.json.set(`account:${doc.id}`, '.', doc); const addr = doc.address; if (addr) { await client.ft.sugAdd(`fAdd`, addr, 1); await client.ft.sugAdd(`pAdd`, addr.substr(addr.indexOf(' ') + 1), 1); } }
App.js is an ExpressJS-based REST API server. It exposes a couple GET endpoints: one for address suggestions and the other for a full-text search of an address. A snippet of the address suggest endpoint below.
app.get('/address/suggest', async (req, res) => { const address = decodeURI(req.query.address); console.log(`app - GET /address/suggest ${address}`); try { let addrs; if (address.match(/^\d/)) { addrs = await client.ft.sugGet(`fAdd`, address); } else { addrs = await client.ft.sugGet(`pAdd`, address); } let suggestions = [] for (const addr of addrs) { suggestions.push({address: addr}) } res.status(200).json(suggestions); } catch (err) { console.error(`app - GET /address/suggest ${req.query.address} - ${err.message}`) res.status(400).json({ 'error': err.message }); } });
Source
Copyright ©1993-2024 Joey E Whelan, All rights reserved.