Explore Developer Center's New Chatbot! MongoDB AI Chatbot can be accessed at the top of your navigation to answer all your MongoDB questions.

Join us at AWS re:Invent 2024! Learn how to use MongoDB for AI use cases.
MongoDB Developer
Ruby
plus
Sign in to follow topics
MongoDB Developer Centerchevron-right
Developer Topicschevron-right
Languageschevron-right
Rubychevron-right

Integrating Atlas Search in a Ruby on Rails Application

Humberto Diaz5 min read • Published Jun 12, 2024 • Updated Aug 12, 2024
Ruby
Facebook Icontwitter iconlinkedin icon
Rate this tutorial
star-empty
star-empty
star-empty
star-empty
star-empty
In the article "Getting Started with MongoDB Atlas and Ruby on Rails," Luce Carter showed us how to integrate MongoDB Atlas in a Ruby on Rails application named Inspiration. Users could capture and organize their creative ideas, thanks to the integration of MongoDB Atlas. In this article, we'll build upon the foundation laid out in Luce’s article and take a deeper dive as we integrate text search directly within our Rails application. By the end of this article, you will have a fully functional search feature embedded in your Rails app, allowing users to efficiently find the ideas they need.

Prerequisites

Before getting started, you will need to complete the following:
  1. Fork and clone a copy of the Inspiration app available on GitHub.
  2. Create a MongoDB Atlas cluster.
  3. Update the development config section inside config/mongoid.yml and add your own connection string.
  4. Ensure that you have data stored in your MongoDB Atlas cluster that you can query against Atlas Search. This should include the ideas you have added to your Inspiration application.
  5. Using the Atlas UI create an Atlas Search index called inspiration. A step by step guide on how to create an Atlas Search index can be found in the Atlas documentation.

Configure the search method in your model

Now that we have our environment properly configured, and our inspiration index created, we can update our model to handle queries to our database. We do this by defining a search method in our Idea model. The method self.search(query): defines a class method named search that takes a single argument query and returns the results.
  • Open your idea.rb file
  • Replace its contents with the content below:
1class Idea
2 include Mongoid::Document
3 include Mongoid::Timestamps
4 field :name, type: String
5 field :description, type: String
6 field :picture, type: String
7
8def self.search(query)
9 aggregation_pipeline = [
10 {
11 "$search": {
12 "index": "inspiration",
13 "text": {
14 "query": query,
15 "path": ['name', 'description']
16 },
17 "sort": {
18 "score": {"$meta": "searchScore"}
19 }
20 }
21 },
22 {
23 "$limit": 20
24 }
25 ]
26 results = collection.aggregate(aggregation_pipeline)
27
28 search_results = results.to_a
29 search_results.map do |result|
30 Idea.new(
31 id: result["_id"],
32 name: result["name"],
33 description: result["description"],
34 picture: result["picture"]
35 )
36 end
37 end
38end
When you call idea.search("example query"), Mongoid constructs and executes a MongoDB query that:
  1. Performs a full text search using Atlas Search on the inspiration index.
  2. Runs a query across the name and description fields.
  3. Sorts the results by their relevance score.
  4. Limits the results to 20. Using a limit is good practice to avoid performance issues if your collection contains millions of documents.
The search_results variable then converts the raw results from MongoDB into an array of hashes that can then be mapped to new Idea instances and rendered in our view files.
1search_results.map do |result|
2 Idea.new(
3 id: result["_id"],
4 name: result["name"],
5 description: result["description"],
6 picture: result["picture"]
7 )
8end

Adding a search action in our IdeasController

Now that we have defined our search query in our Idea model, we need a way to initiate that search. We do this by adding a search action in our IdeasController. Add the following code to your IdeasController:
1def search
2 @query = params[:query]
3 @ideas = @query.present? ? Idea.search(@query) : Idea.all
4 render :display_results
5 end
With this setup, when you submit a search query it will call the search method in the Idea model to perform the search. The results will then be rendered in our view files.

Generating our search controller

We will be creating a separate SearchesController to handle search requests and to display the search results.
Run the following command to generate the SearchesController and the display_results view file.
1rails generate controller Searches display_results
Open your searches controller.rb file and add the following code.
1class SearchesController < ApplicationController
2 def display_results
3 query = params[:query]
4 @results = Idea.search(query)
5 end
6end
Open the file display_results.html.erb and add the below, which will return our search results.
1<div class="search-results">
2 <h1>Search Results for "<%= params[:query] %>"</h1>
3
4 <% if @results.empty? %>
5 <p>No ideas found.</p>
6 <% else %>
7 <div class="idea-container">
8 <% @results.each do |result| %>
9 <div class="idea">
10 <h2><%= result.name %></h2>
11 <p><%= truncate(result.description, length: 150) %></p>
12 <img src="<%= result.picture %>" alt="<%= result.name %>" />
13
14 <p><%= link_to "View", idea_path(result.id) %></p>
15 </div>
16 <% end %>
17 </div>
18 <% end %>
19</div>
20
21<%= link_to "Back", ideas_path %>
In your application.css file, add the below to create some basic styling for your search results:
1.search-results {
2 /* Add styles for the search results container */
3 width: 80%;
4 margin: 0 auto;
5 }
6 .idea-container {
7 display: flex;
8 flex-direction: column;
9 }
10 .idea {
11 padding: 20px;
12 border-bottom: 2px solid #ccc;
13 border-radius: 10px 10px 0 0;
14 margin-bottom: 10px;
15 }
16 .idea h2 {
17 margin: 0;
18 }
19 .idea p {
20 margin: 0;
21 }
22 .idea img {
23 width: 100px; /* Adjust the width of the image */
24 height: auto; /* Maintain aspect ratio */
25 display: block; /* Ensure the image takes up full width */
26 }
27 /* Remove bullet points */
28 ul {
29 list-style-type: none;
30 padding: 0;
31 }
With this setup, when you submit a search query, it will be routed to the SearchesController, which will call the search method in the Idea model to perform the search. The results will then be displayed in the display_results view.

Creating the search form

Now, we just need to create a simple UI so that users can submit queries directly in our Rails application.
  • Open your index.html.erb.
  • Copy and paste the code below to add a search form and a placeholder for search results.
1<%= form_tag(search_results_path, method: :get, class: "form-inline") do %>
2 <div class="input-group mb-3">
3 <%= text_field_tag :query, params[:query], placeholder: "Search Ideas...", class: "form-control" %>
4 <div class="input-group-append">
5 <%= submit_tag "Search", class: "btn btn-primary text-white" %>
6 </div>
7 </div>
8 <% end %>
  • Add the following styling for the search bar in your application.css file:
1.input-group {
2 width: 100%;
3}
4
5.btn-primary {
6 background-color: #007bff;
7 border-color: #007bff;
8 color: white;
9}
10
11.btn-primary:hover {
12 background-color: #0056b3;
13 border-color: #004085;
14}

Updating our routes to include our search results

To redirect users to the display_results view file, we need to update our routes.rb.
Add the following get request to your routes file:
1Rails.application.routes.draw do
2 root to: "ideas#index"
3
4 resources :ideas
5 get '/search_results', to: 'searches#display_results', as: "search_results"
6end

Running our local server

It’s time to test out our application. Begin by running the following command in your project directory:
1rails server
Navigate to Port: 3000 and you should now be able to see a search bar appear on the web page.
Index pages listing out all ideas in our application

Submit a query on the app

To submit a search, add your query term in the search bar and click on “Search.”
Here are the results of a search in my MongoDB database for the word “pet”: A list of ideas are displayed matching the search term "pet."
Please note that search results are dependent on the contents of your own database. So make sure your database has the data you are requesting. However, as the complexity of your data increases, the need for more advanced search queries may be necessary. Refer to the MongoDB documentation for information regarding these queries.

Summary

And with that, we now have a fully functional search feature integrated into our Rails application. This integration not only enhances the usability and functionality of our application but can also help improve user engagement. Our Rails app now offers a powerful tool for users to find and manage their creative ideas effectively. Be sure to explore more about MongoDB Atlas and Rails in the community forums, share your experiences, or ask any questions you may have!

Facebook Icontwitter iconlinkedin icon
Rate this tutorial
star-empty
star-empty
star-empty
star-empty
star-empty
Related
Tutorial

Calling the MongoDB Atlas Administration API: How to Do it from Node, Python, and Ruby


Jun 18, 2024 | 4 min read
News & Announcements

A Plan for MongoDB and JRuby


Jun 23, 2022 | 2 min read
Tutorial

Getting Started with MongoDB Atlas and Ruby on Rails


Dec 11, 2023 | 6 min read
Article

MongoDB ORMs, ODMs, and Libraries


Aug 28, 2024 | 3 min read
Table of Contents