Welcome folks today in this blog post we will be building a next.js redisearch fulltext autocomplete search
field using redis cloud
database. All the step by step instruction is given below.
Create Next.js Project
First of all you need to create a new next.js
project by executing the below command
1 |
npx create-next-app redisautocomplete |
1 |
cd redisautocomplete |
Installing Dependencies
For this project we need to install the redis-om package to connect to the redis cloud database
1 |
npm i redis-om |
So now you need to create a new account inside the redis
website and create a new database as shown below
Creating Environment Variables
So for this project you need to create the REDIS_URL
variable inside the .env file as shown below
.env
1 |
REDIS_URL=redis://default:PASSWORD@HOST:PORT |
Here you need to replace the password , Host & Port number of your redis cloud account
Writing the Connection Code For Redis Cloud
Now guys just make a new folder called as lib and inside it create a new file called redis.js
and copy paste the below code
redis.js
1 2 3 4 5 6 7 8 9 |
import { Client, Entity, Schema, Repository } from 'redis-om'; const client = new Client(); async function connect() { if (!client.isOpen()) { await client.open(process.env.REDIS_URL); } } |
So here in the above lines of code we are importing the Client
Class from redis-om
package and we are first of all making a new object of the Client
class and then inside the async function we are using the open
method to actually connect to the redis
database using the url
which is stored inside the .env file
Defining the Schema
Now guys we will define the model and schema for the application. We will have a Car class having some properties as shown below. Inside the same file redis.js
file copy paste the below code
1 2 3 4 5 6 7 8 9 10 11 12 13 |
class Car extends Entity {} let schema = new Schema( Car, { make: { type: 'string' }, model: { type: 'string' }, image: { type: 'string' }, description: { type: 'string', textSearch: true }, }, { dataStructure: 'JSON', } ); |
Here guys the Car class is extending the Entity class so that we can define the schema
for the car such as model name, description of car and image of car etc. Lastly we are defining the schema to be inside JSON
structure
Saving the Document in Redis Cloud
After defining the schema
guys now it’s time to save some data to the redis
cloud database. Inside the same file redis.js
just write the below function which will take the car object as an argument and insert it into redis
database
1 2 3 4 5 6 7 8 9 10 |
export async function createCar(data) { await connect(); const repository = client.fetchRepository(schema) const car = repository.createEntity(data); const id = await repository.save(car); return id; } |
Here you can see we are creating a new car
model and inserting it into redis
database. Basically this is an async function and then we are saving the data using the save
method
Create Next.js API Route
Now guys we will creating a next.js
route to handle the insertion
process inside the redis cloud. For this you need to go to pages directory of your next.js project and inside it api directory create a car.js file and copy paste the below code
pages/api/cars.js
1 2 3 4 5 6 |
import { createCar } from '../../lib/redis'; export default async function handler(req, res) { const id = await createCar(req.body); res.status(200).json({ id }) } |
So here guys we are importing the redis.js
file from the lib
folder in the very first line and then we are using the createCar
function to create a brand new car and insert into redis
database and also lastly we return a json
response to the client
React HTML Form Component
Now guys we will create a html form
to collect user data to insert into redis database
Inside the lib
folder make a CarForm.js
file and copy paste the below code
lib/carForm.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
export default function CarForm() { const handleSubmit = async (event) => { event.preventDefault(); const form = new FormData(event.target); const formData = Object.fromEntries(form.entries()); const res = await fetch('/api/cars', { body: JSON.stringify(formData), headers: { 'Content-Type': 'application/json', }, method: 'POST', }); const result = await res.json(); console.log(result) }; return ( <form onSubmit={handleSubmit}> <input name="make" type="text" /> <input name="model" type="text" /> <input name="image" type="text" /> <textarea name="description" type="text" /> <button type="submit">Create Car</button> </form> ); } |
Here guys we are making a simple fetch
post call to the actual next.js api route to insert data to redis cloud database. In the html
form we have three fields namely as follows
name of the car
model
number of car
image
of car
description of car
Creating the Index Using RediSearch
Now guys we need to create the index
using redisearch. Now in the lib
folder and in the redis.js
file copy paste this function code
lib/redis.js
1 2 3 4 5 6 |
export async function createIndex() { await connect(); const repository = new Repository(schema, client); await repository.createIndex() } |
Now we need to create a new next.js
api route for executing this javascript function of createIndex
pages/api/createIndex.js
Now inside the pages
directory and inside api create a new file called createIndex.js
file and copy paste the below code
1 2 3 4 5 6 |
import { createIndex } from '../../lib/redis'; export default async function handler(req, res) { await createIndex(); res.status(200).send('ok'); } |
Searching Data in Redis
Now guys it’s time to search the data
stored inside the redis
database. For this you need to add this function code inside redis.js
file as shown below
lib/redis.js
1 2 3 4 5 6 7 8 9 10 11 12 13 |
export async function searchCars(q) { await connect(); const repository = new Repository(schema, client); const cars = await repository.search() .where('make').eq(q) .or('model').eq(q) .or('description').matches(q) .return.all(); return cars; } |
Now guys we will create the api route
to handle this search query. For this you need to create search.js
file inside the pages/api
directory as shown below
pages/api/search.js
1 2 3 4 5 6 7 |
import { searchCars } from '../../lib/redis'; export default async function handler(req, res) { const q = req.query.q; const cars = await searchCars(q); res.status(200).json({ cars }); } |
Here guys we are just searching
live using the query which is received inside the function as an argument. This is real autocomplete search field using the redis database
Creating the Autocomplete Form
Now for creating the Autocomplete form guys you need to create a SearchForm.js file inside the lib folder as shown below
lib/SearchForm.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
import { useState } from 'react'; export default function SearchForm() { const [hits, setHits] = useState([]); const search = async (event) => { const q = event.target.value; if (q.length > 2) { const params = new URLSearchParams({ q }); const res = await fetch('/api/search?' + params); const result = await res.json(); console.log(result); setHits(result['cars']); } }; return ( <div> <input onChange={search} type="text" /> <ul> {hits.map((hit) => ( <li key={hit.entityId}> {hit.make} {hit.model} </li> ))} </ul> </div> ); } |
So here in this autocomplete
form we are also using the react hooks
to store the query of the user and then we are attaching the onchange
event so whenever the input field value is changed it will show the autocomplete suggestion to the user what the record is looking like according to the query supplied by the user.
Final Code
Now to run this app you need to include all the components inside the index.js
file of your next.js app as shown below
index.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
import Head from 'next/head' import CarForm from '../lib/CarForm' import SearchForm from '../lib/SearchForm' import styles from '../styles/Home.module.css' export default function Home() { return ( <div className={styles.container}> <Head> <title>Create Next App</title> <meta name="description" content="Generated by create next app" /> <link rel="icon" href="/favicon.ico" /> </Head> <CarForm/> <SearchForm/> </div> ) } |
So here we are including all the forms
of the application such as car form
and autocomplete form
to search the cars
Now start the next.js app by executing the below command as shown below
npx run dev