# Typesense search with Ruby on Rails #225

- URL: https://superails.com/posts/typesense-search-with-ruby-on-rails-225
- Published: 2025-01-22
- Duration: 14:07
- Access: free
- Topics: Typesense, search

Previously I did the obvious thing and searched my Postgres database for Posts by "title".

But when you need to scale your search due to a a large dataset, or want to use advanced search features (image/voice/ignore typos, etc), you might want to spin up a separate search server.

The usual suspects are Typesense, Elasticsearch, Meilisearch & Algolia.

In this episode we will create an index of our Posts on our own Typesense server.
Next, we will perform search and render results by sending requests to our Typesense API endpoint

TEXT walkthrough: https://blog.corsego.com/typesense-rails
Typesense source code: https://fnf.dev/3ZIAjId
Gem Typesense-ruby: https://fnf.dev/3PHqHcb
Gem Typesense-rails: https://fnf.dev/4jBiZhw
Integrating Typesense into SupeRails (members only): https://fnf.dev/40t6NX4

0:00 Different search engine APIs
02:02 About Typesense
3:30 Install Typesense
4:25 Typesense API - collections, documents, index all posts
8:25 Update Typesense index on Post Create/Update/Destroy
9:29 Typesense API to search collection
10:25 Rails Controller, views
12:00 Typesense-rails integration
13:00 Deploy to Production?

Thanks so much to Typesense for sponsoring this video! 
I had a lot of fun integrating the search server with Rails.

## Chapters

- 0:00 Different search engine APIs
- 02:02 About Typesense
- 3:30 Install Typesense
- 4:25 Typesense API - collections, documents, index all posts
- 8:25 Update Typesense index on Post Create/Update/Destroy
- 9:29 Typesense API to search collection
- 10:25 Rails Controller, views
- 12:00 Typesense-rails integration
- 13:00 Deploy to Production?

## Transcript

So in my application, I have 270 records, and at the moment I can search them all by title. So here I have the search field, I'll search for hot fire. And as I search, uh, uh, you see there are the results that match hot via in the title. It works like this. In the post model, I have defined, uh, scope. So here it is, I search by title with I like, so, uh, case insensitive. And, uh, it works okay, but if I make a typo, like two letters are, then you see there is no search match and they're all human. We can all make mistakes. And at the moment the search works quite well on one attribute. Now, I could also add search by description, but possibly the search would be a tiny bit slower but still have 270 records. And that is nothing for Postgres. But as your application scales, you might have 270,000 or even millions of records and you would likely want to, um, scale your search and maybe move it to an external service. So the first things that come to mind are Elasticsearch. There's also Algolia, mail search and type senses. Now I've seen Elasticsearch installed in a few ribbon drills applications over the years, and I always felt that it's like a very, very heavy integration that is, uh, uh, hard to install and maintain and, um, in the type sense, uh, uh, website, there's, there's thing no PhD required. So that kind of, uh, resonates with me. I don't have PhD and I don't want to spend all my life maintain Elasticsearch. Um, anyway, so we've got Elasticsearch. There's also a, Golia is actually a French, uh, company and they also work with rub rails, and that's mail search. And then there is, uh, type sense. Um, I found a nice comparison of, uh, all of these options on the type sense website. So for Elastic search, it says that, uh, um, if you've got like petabytes of data, like logs, then you might want elastic search, otherwise you can, uh, go with another option. Now, algo is fully closed source, so it's just like an API that you integrate with. Uh, mail search and type senses are, uh, open source. And uh, in this episode we're going to focus on type senses. So here is that type sense source code. It's all free. You can, uh, install it locally. You can, uh, push it to, to your own server. So, um, on the type sense, uh, website, actually it was cool to see all the features. I didn't know that there are so many different, uh, features around the search. So obviously typo tolerance, something I have mentioned here and trying to type hot wire with, uh, typo. Uh, then there's uh, uh, I mean search for by images voice, uh, and uh, like conversational search, is this even a thing? So there are so many, like I know businesses that you can even build around the, uh, search itself. And there are a few examples of, uh, searching large data sets. So for example, a session songs I'll try to search for yesterday from the Beatles. So you see I made some typos and it's still, uh, Considering the typos found the best me result out of 32 million, uh, songs. So that's, uh, really cool. Um, yeah, let's try installing type sense in a Ruben Journals application. So here in my application, I'm going to search not only by title but also by description. And I'm gonna to use type, uh, type sense instead of, uh, the skill, uh, search that I'm doing here. So, uh, uh, to install type sense. First of all, I'm going to go to their docs. So, uh, going to their website, uh, docs guide, install type sense. So I'm not going to do it via Docker. I am not a big fan of Docker, uh, local especially. Then I'm going to run Bruin install type sense. And then I'm gonna start the type sense server. This was fast, okay, it says successfully study type sense server. And we can make a CRL request to local host 81 0 8 slash health. So by default it started the type sense at the local host 81 0 8, and you say, I made this request and it says, okay, true. Let's actually drive this in this CRL, uh, you see. So it actually has a web server running and it has this health page. Uh, looks quite cool. Uh, now how can we interact the type sense? So to do this, we have this, uh, gem type sense, uh, Ruby. So, uh, I'm going to add the gem type sense Ruby to my application. I've actually already done it. Um, and here's the pull request, and they're going to go through all the changes that I have done. So, um, here I added the G types senses, and next I added an initializer. So types senses are B, let's have a look at this, uh, file in the VS code. So I create a new types senses client, uh, with, uh, host, local host, the port 81 0 8, the one that was, uh, started the, uh, from the terminal. And the default, API key is, uh, X, Y, Z that we're using. Uh, okay, so I started the server and now I created a small, uh, service to interact with the API. So here I have this type sense service, and here I can create a schema. So types can have like collections of records of objects that you can search through. So I have a collection of named posts and the post collection has attributes, subtitled body created at and default. We're going sort by, uh, created at. So we are going to, uh, create this kind of schema inside, uh, types, and they're going to load, uh, our posts into it. And posts are going to be documents. So collections are like, uh, tables and documents are records inside the tables. So I'm going to call the types and servers from our rails console, um, types and service, uh, dot, uh, create schema. We have created the schema. Let's try retrieve the schema for post. Uh, so types and service, uh, gets schema. It's going to get the schema for post. Now you see here in my service it, everything is around post. Uh, then, uh, let's try exporting the documents. So, uh, kind of the payload of everything they have for these documents. You see at the moment it's empty. Uh, so let's load all our posts into the, uh, type sense, uh, collection of posts. Uh, to do this, I have also created, uh, rate task. So type rake, if, if you don't yet have a type senses, uh, collection created, it's going to create a collection and it's going to load all our posts into, uh, that collection. And you see we have this command index post. So for each post we're going to, uh, get the collection of posts inside, do absence, and uh, create a new post with the ID titled body and, uh, created at timestamp. So, um, I'm going to run this command. I can run it, uh, uh, either for Rails console or using Rails types and setup, run this r task. Okay, let's start the console and scan. So let's say post do count, we have 270 posts. And let's, uh, see the data that we have tried to push to types and, and see if it was successful. So I will say types and service dot, um, export documents. And you see we have a big payload of, uh, all the documents that, all the posts that we have pushed to our, uh, collection. Let's try getting a document, uh, count. So types and service dot documents count. You see it's the hundred 70 at the same amount as uh, posts in our application. So we have pushed all our posts and let's try getting a post by id. So, um, they post do first, uh, dot id and dot title. Okay, and let's, uh, uh, run types and service retrieve document and the ID will be six. And here we have, uh, the title from, uh, our Posts database and the title from Type Senses. So see it is the same record. Now we can interact with the type sense API, but we want to be able to update the, uh, collection of, uh, indexed posts in types and never something changes in the active record. So whenever a post is created, we want to add it to the index. When the post is updated, we want to update the index, and then the post is deleted. We want to remove from the index. So for this, I created the three callbacks. So, uh, after the creation, uh, Intex post, after update, update, post, after destroy, delete post, and in the steps in service, I have these defined. So find the collection of posts, find that document by the post ID and delete it or update it or create it. Okay? So, uh, let's uh, see it in action. I'm going to try to change the title of, uh, this post. So post first update title full 12. Okay, and let's find the document. You see it in the document there. Title has also been updated. So, uh, our callbacks work. Okay, now let's uh, go to the next step. So we have the types index. Now we want to do the types and search. So we also created this, uh, command search post. And uh, we are going to make this, uh, call to kind of the type sense API to our local types and server. And we're going to search the documents by this. Search parameters. We're searching by title and body of a post. The default sold is by created the at the descendant. We add some pagination and the quantity of items per page. So let's try searching. First of all, in the rails console. Um, I will say types and server dot search posts and filter will be hot via. And you see we got, uh, a big payload and now we can do it from our rails, uh, controller. We can, uh, uh, sanitize the payload and display it in the rails view. So here I have already actually implemented it. Here I have, uh, the uh, URL post slash search. And here I have, uh, a search field. So, uh, in our roots inside posts, uh, I created a collection for search. Then in the post controller, I created this dev search. And you see if there is a very parameter in this search form. Then we're going to hit the types and API from the search and render the results in a sanitize the object of both. We're going respond in JSON and in HTML, but we don't have to really respond in js. It's just, uh, an additional response type that we can have in the application. Let's even comment it out Alpha now. And so let's search for Hot Fire. Hot Fire. You see the results have been loaded and each time, uh, when we make the search, we kind of search not in uh, uh, the Rails posts database, but we search in type sense and uh, we render the results. Let's even make some typos or JSO, um, instead of JSO, and you see the results are being loaded. I can also add some kind of like additional, uh, points from anywhere in the title or description, and it's going to show the most relevant results. So we perform the search, uh, using uh, uh, type sense, it works well. Let's, uh, try the J endpoint. Let's, uh, try doing JS O. And you see we have the results in the JSO Looks really cool. Now, uh, there are a couple of more things we can do with the type sense. So uh, we can make a serial l requests with our API key to retrieve something from our collections. So let's try getting, uh, a specific document. Okay, there's no document that I did too, but I remember there is document that I did six and you see we get the payload and we can also get the stats, Jason. So the stats of our uh, type Senses server, uh, yeah, that's, uh, about it. So, uh, I'm going to leave a link to the implementation, uh, and to the types and services that I have created in the description of this video so that you can implement type sense in your Rails application. And I see the Type Sense is currently working on an additional integration except of Type Sense Ruby. It'll be Type Sense Rails. It is going to based on a Algos Rails integration. So hopefully the API is going to be really similar and, uh, it should be possibly even easier to install type Sense in Rails application. And as the final step would be to deploy to production. So, uh, now we have this type sense server running, uh, locally at uh, 8 1 0 8 and we would want to push it to production so that we can use it in our real application. And uh, if we go to the Type Sense Docs, there should be some options on how to do it, uh, how to push types to production, uh, for it to be self-hosted, but they also offer the STS cloud. So if I go here, um, what's the pricing? So 720 hours is like a month, and it is, uh, the cheaps version is, uh, $21 per month if they are hosting it. Uh, if you're not hosting it yourself. And, uh, another interesting thing I noticed, if you go to the login and go to Inspect Element, you can see that they are using Hot Wire and most likely also rails for their sars. So yeah, that's, uh, the basic implementation of type sense in Ribbon Rails application. I invite you to try type sans.
