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.
