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.