DEV Community

Joshua Evuetapha
Joshua Evuetapha

Posted on

How to Integrate Typesense Search Engine in a Nodejs application

Tried building an application that requires efficient search? Maybe an online store or library catalog system?

It is hard to build search engines that are typo tolerant, effective and efficient. A typographical error could make a search return nothing even though the requested item is on the database.
Typesense could save you and your app users from such stress as you would not need to spend time building a search engine. And your users can effectively use the search feature in your application which would give them a great user experience.
Typesense is an open-source typo-tolerant search engine for developers, developed to reduce the time to market for apps that require effective and efficient search.

In this article, we will cover the following:

  • Setting up Typesense Cloud
  • Setting up our nodejs app
  • Initializing the client
  • Creating a Typesense Collection
  • Setting up the express app
  • Adding item to our collection
  • Searching our collection

Setting up Typesense Cloud

You can use Typesense by either installing its docker image on your server or using the Typesense cloud hosting solution, which is the easiest way to get started with it, so we are using this option. Click Here to get started and sign in with Github.

Once authenticated, follow these steps.

  1. Scroll down and launch a cluster wait for about 4 to 6 minutes.

Creating A Cluster

  1. Click on Generate API Keys. It will download a text file containing credentials needed to authenticate our app with Typesense cloud.

Generate API Key

Setting Up the Nodejs App

Follow these steps, if you have Nodejs installed on your system if you don't download the latest version here and follow the steps.

npm init
Enter fullscreen mode Exit fullscreen mode

Install the following packages express, typesense and nodemon by running the following command

npm i express typesense nodemon
Enter fullscreen mode Exit fullscreen mode

Add "dev": "nodemon app.js" to the script part of the package.json file.

"scripts": {
        "start": "node app.js",
    "dev": "nodemon app.js"
  },
Enter fullscreen mode Exit fullscreen mode

After these are done, setup the project structure to look like this.

📦express-typesense-app

┣ 📂Typesense

┃ ┣ 📜bookCollection.js

┃ ┗ 📜client.js

┣ 📜app.js

┣ 📜package.json

┗ 📜package-lock.json

Initializing the client

Navigate to the Typesense Folder, paste codes below in the client.js file, The first line imports Typesense into our code, then we create a Typesense Client instance, this instance receives an object of configurations, needed to authenticate our app with Typesense, next we export this client so it will be available for other files. Fill in the information gotten from the text file downloaded when you generated API keys, since we are running on the backend and we want to have write access use the Admin API Key.

const Typesense = require('typesense')

const client = new Typesense.Client({
  nodes: [{
    host: 'your-typesense-node-gotten-from-type-sense-cloud', // For Typesense Cloud use xxx.a1.typesense.net
    port: '443',      // For Typesense Cloud use 443
    protocol: 'https'   // For Typesense Cloud use https
  }],
  apiKey: 'your-typesense-admin-api-key-gotten-from-type-sense-cloud',
  connectionTimeoutSeconds: 5
})

module.exports = client
Enter fullscreen mode Exit fullscreen mode

Creating a Typesense Collection

Typesense, a collection is a group of related documents, by are like tables in relational a database. When we create a collection, we give it a name and describe the fields that will be indexed when a document is added to the collection.

For each field, we define its name, type, and whether it's a facet field. A facet field allows us to cluster the search results into categories.

We also define a default_sorting_field that determines how the results must be sorted when no sort_by clause is provided. In this case, books that have more ratings will be ranked higher. This line of code client.collections().create(booksSchema) create the book collection from the book schema.

This code will throw an error if the collection already exists, to prevent the app from this crashing handle the Error, by calling the error callback. as done in the code below err => {}.


const booksSchema = {
    'name': 'books',
    'fields': [
      {'name': 'title', 'type': 'string' },
      {'name': 'authors', 'type': 'string[]', 'facet': true },
      {'name': 'image_url', 'type': 'string' },
      {'name': 'publication_year', 'type': 'int32', 'facet': true },
      {'name': 'ratings_count', 'type': 'int32' },
      {'name': 'average_rating', 'type': 'float' }
    ],
    'default_sorting_field': 'ratings_count'
  }

client.collections().create(booksSchema)
  .then( data => {

  }, err => {

  });
Enter fullscreen mode Exit fullscreen mode

Setting up the express server

Create app.js on the root directory of the application, we import the express this is needed to create an express server, line 2 imports the Typesense client this client will be used to make requests to Typesense, line 3 creates the book Collection if it doesn't exist.

const express = require('express');
const client= require('./Typesense/client');
require('./Typesense/bookCollection')
Enter fullscreen mode Exit fullscreen mode

Here we create an express app, the next two lines of codes attach the middleware needed for the app to receive post data from post request.

const app = express();

app.use(express.urlencoded({ extended: true }));
app.use(express.json());
Enter fullscreen mode Exit fullscreen mode

Searching for books in our collection

This route handles GET requests to localhost:3000/search?q=, the first line of code in this route get the user search input from the q query, the second line builds the search object searchParameters, from the search object we see that we are querying our books by its title and sorting by ratings_count in descending order, res.send(searchResults) sends the search results to the client.


app.get('/search', (req, res) => {

  const { q } = req.query;

  const searchParameters = {
    'q'         : q,
    'query_by'  : 'title',
    'sort_by'   : 'ratings_count:desc'
  }

  client.collections('books')
    .documents()
    .search(searchParameters)
    .then(function (searchResults) {
      res.send(searchResults)
    }, err => { res.send(error) } )
});
Enter fullscreen mode Exit fullscreen mode

Adding data to book collection

This route handles POST request to localhost:3000/add-book, the first line of code get the body of the post request, which in this case is the book we want to add to our collection client.collections('books').documents().create(book) add the book to our collection. res.send(data) sends the book data to the client.


app.post('/add-book', (req, res) => {

  const book = req.body;

  client.collections('books').documents().create(book).then(data => {
    res.send(data)
  }, err => {
    res.send(err)
  })

});
Enter fullscreen mode Exit fullscreen mode

This codeblock runs the server on port 3000


const port = process.env.PORT || 3000;

const server = app.listen(port, () => {
  console.log(`App running on port ${port}...`);
});
Enter fullscreen mode Exit fullscreen mode

Adding Item to our Collection

I will be using Postman to test this app, if you are new to Postman, click here to download it, set up a workspace, and create a collection.

I added 3 books to the book collection, titled How to use Typesense in a Nodejs application, I want to Dance, Best Dance Move with the following ratings respectively 4.55, 3.55, 4.35.

Adding Books

Searching for Item in our Collection

Searching for a book titled Best Dance Moves, Noticed, I deliberately made errors in the spelling by searching Bezt Dense Movee

and Typesense returns Two books that contain the word Dance in its title.

Searching For Book

Searching for a "Harry Potter" which is not in our book collection returns zero items.

Harry Potter search

Conclusion

In this article, we talk about Typesense and how to get started with Typesense cloud, connecting to Typesense cloud, we created a typesense collection. We used the Typesense javascript library, this library works also works on Web Browsers, when used on Web Browser, use the search API key that doesn't grant write access. Typesense supports other languages click here to learn about them.

Using Postman to test our application we saw that Typesense is very typo tolerant, easy to use, and fast.

Discussion (0)