Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 6 additions & 1 deletion source/interact-data.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ Interact with Data
Search Text </interact-data/text-search>
Transactions and Sessions </interact-data/transaction>
Nested Attributes </interact-data/nested-attributes>
Tutorial: Atlas Search </interact-data/atlas-search-tutorial>

In this section, you can learn how to use {+odm+} to interact with your
MongoDB data.
Expand All @@ -44,4 +45,8 @@ MongoDB data.
transactions to make atomic data changes.

- :ref:`mongoid-data-nested-attr`: Learn how to modify documents and
their associations in a single operation.
their associations in a single operation.

To learn how to integrate the Atlas Search feature into an application,
see the :ref:`Integrate Atlas Search into a {+ror+} App Tutorial
<mongoid-atlas-search-rails-tutorial>`.
331 changes: 331 additions & 0 deletions source/interact-data/atlas-search-tutorial.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,331 @@
.. _mongoid-atlas-search-rails-tutorial:

=========================================================
Tutorial: Integrate Atlas Search into a {+ror+} App
=========================================================

.. facet::
:name: genre
:values: reference

.. meta::
:keywords: code example, transform, pipeline

.. contents:: On this page
:local:
:backlinks: none
:depth: 2
:class: singlecol

Overview
--------

In this tutorial, you can learn how to integrate :atlas:`Atlas Search
</atlas-search/>`, an advanced text search feature, into a {+ror+} app.

After you complete this tutorial, you have a fully functional search
feature embedded in your Rails app, allowing you to efficiently find
information.

Prerequisites
-------------

The tutorial builds on a template app that you can download from the
:github:`mongodb-atlas-with-ruby-on-rails-example GitHub repository
<mongodb-developer/mongodb-atlas-with-ruby-on-rails-example>` by running
the following command:

.. code-block:: bash

git clone https://github.com/mongodb-developer/mongodb-atlas-with-ruby-on-rails-example.git

Then, set up the following components:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

S: since each list item is more of an action rather than a component:

Suggested change
Then, set up the following components:
Then, perform the following setup actions:


1. Create a MongoDB Atlas cluster. To learn how to create a cluster, see
the :ref:`mongoid-quick-start-rails-create-deployment` step of the
Rails Quick Start guide.

#. Update the app's ``config/mongoid.yml`` file with your own connection
string and set the default database to ``inspiration``, as shown the
following example configuration:

.. code-block:: yml

development:
clients:
default:
uri: mongodb+srv://<username>:<password>@<host>/inspiration

#. Start the Rails app by running the ``rails server`` command, then
complete the :guilabel:`New Idea` entry form to insert some sample
data into the ``inspiration.ideas`` collection.

.. tip:: Sample Data

To successfully demonstrate the search functionality later in
the tutorial, insert sample documents that contain some overlapping
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

S: this wording seems a little clearer to me since the tutorial is demostrating:

Suggested change
To successfully demonstrate the search functionality later in
the tutorial, insert sample documents that contain some overlapping
To achieve the search functionality demonstrated later in
the tutorial, insert sample documents that contain some overlapping

terms.

#. Create an Atlas Search index in Compass or the Atlas UI called
``inspiration`` with dynamic mappings. To learn more about creating
Atlas Search indexes, see the :atlas:`Manage Atlas Search Indexes
</atlas-search/manage-indexes/>` guide in the Atlas documentation.

Steps
-----

.. procedure::
:style: connected

.. step:: Configure the Atlas Search feature in your {+odm+} model.

First, update the ``Idea`` model to handle queries to our
database by defining the ``search`` method in the model. The
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

S:

Suggested change
First, update the ``Idea`` model to handle queries to our
database by defining the ``search`` method in the model. The
First, update the ``Idea`` model to handle database queries
by defining the ``search`` method in the model. The

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reworded

method ``self.search(query)`` defines a class method called
``search`` that takes a single argument ``query`` and returns the
results.

Open the ``app/models/idea.rb`` file and replace its contents with
the following code:

.. code-block:: ruby

class Idea
include Mongoid::Document
include Mongoid::Timestamps
field :name, type: String
field :description, type: String
field :picture, type: String

def self.search(query)
aggregation_pipeline = [
{
"$search": {
"index": "inspiration",
"text": {
"query": query,
"path": ['name', 'description']
},
"sort": {
"score": { "$meta": "searchScore" }
}
}
},
{
"$limit": 20
}
]
results = collection.aggregate(aggregation_pipeline)

search_results = results.to_a
search_results.map do |result|
Idea.new(
id: result["_id"],
name: result["name"],
description: result["description"],
picture: result["picture"]
)
end
end
end

When you call ``idea.search("<example query>")``, {+odm+} performs the
following actions:

1. Performs a full-text search by using the ``inspiration`` index.
#. Runs the query across the ``name`` and ``description`` fields.
#. Sorts the results by their relevance scores.
#. Limits the number of results to ``20`` to improve performance
for queries on large collections.

The ``search_results`` variable then converts the raw results from
MongoDB into an array of hashes that can be mapped to ``Idea``
model instances and rendered in your view files.

.. step:: Add a Search action in your controller.

Now that you defined the Search query functionality in the
``Idea`` model, you must add an action to initiate queries.

Open the ``app/controllers/ideas_controller.rb`` file and add the
following action to your ``IdeasController`` before the ``private``
declaration:

.. code-block:: ruby

def search
@query = params[:query]
@ideas = @query.present? ? Idea.search(@query) : Idea.all
render :display_results
end

Now, when you submit a Search query, {+odm+} runs the
``search`` method in the ``Idea`` model. The
results are then rendered in your view files.

.. step:: Generate the Search controller.

In this step, you create a ``SearchesController`` to handle Atlas Search
requests and display results.

Run the following command to generate the ``SearchesController``
and the ``display_results`` view file:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

S: I don't think you need the step intro sentence

Suggested change
In this step, you create a ``SearchesController`` to handle Atlas Search
requests and display results.
Run the following command to generate the ``SearchesController``
and the ``display_results`` view file:
Run the following command to generate the ``SearchesController``
and the ``display_results`` view file, which handle Atlas Search requests and display the results:


.. code-block:: bash

rails generate controller Searches display_results

Open the newly created ``searches_controller.rb`` file and replace
the contents with the following code:

.. code-block:: ruby

class SearchesController < ApplicationController
def display_results
query = params[:query]
@results = Idea.search(query)
end
end

Open the ``app/views/searches/display_results.html.erb`` file and
replace the contents with the following code, which renders the search results:

.. code-block:: html

<div class="search-results">
<h1>Search Results for "<%= params[:query] %>"</h1>

<% if @results.empty? %>
<p>No ideas found.</p>
<% else %>
<div class="idea-container">
<% @results.each do |result| %>
<div class="idea">
<h2><%= result.name %></h2>
<p><%= truncate(result.description, length: 150) %></p>
<img src="<%= result.picture %>" alt="<%= result.name %>" />

<p><%= link_to "View", idea_path(result.id) %></p>
</div>
<% end %>
</div>
<% end %>
</div>

<%= link_to "Back", ideas_path %>

Then, add the following code to your ``app/assets/stylesheets/application.css`` file to include
basic styling for the search results:

.. code-block:: css

.search-results {
width: 80%;
margin: 0 auto;
}
.idea-container {
display: flex;
flex-direction: column;
}
.idea {
padding: 20px;
border-bottom: 2px solid #ccc;
border-radius: 10px 10px 0 0;
margin-bottom: 10px;
}
.idea h2 {
margin: 0;
}
.idea p {
margin: 0;
}
.idea img {
width: 100px;
height: auto;
display: block;
}
ul {
list-style-type: none;
padding: 0;
}

.. step:: Create the Search form.

To enable Search queries directly in your application, open the
``app/views/ideas/index.html.erb`` file and add the following
code:

.. code-block:: html

<%= form_tag(search_results_path, method: :get, class: "form-inline") do %>
<div class="input-group mb-3">
<%= text_field_tag :query, params[:query], placeholder: "Search Ideas...", class: "form-control" %>
<div class="input-group-append">
<%= submit_tag "Search", class: "btn btn-primary text-white" %>
</div>
</div>
<% end %>

Add the following styling for the search bar to your ``application.css`` file:

.. code-block:: css

.input-group {
width: 100%;
}
.btn-primary {
background-color: #007bff;
border-color: #007bff;
color: white;
}
.btn-primary:hover {
background-color: #0056b3;
border-color: #004085;
}

.. step:: Update app routes for Search queries.

Replace the existing route in the ``config/routes.rb`` file with
following route to display search results:

.. code-block:: ruby

Rails.application.routes.draw do
root to: "ideas#index"
resources :ideas
get '/search_results', to: 'searches#display_results', as: "search_results"
end

.. step:: Start your application and run Search queries.

Run the following command to start your application:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

S:

Suggested change
Run the following command to start your application:
In your project directory, run the following command to start your application:


.. code-block:: bash

rails server

Navigate to http://127.0.0.1:3000/ to view the landing page.

Check failure on line 307 in source/interact-data/atlas-search-tutorial.txt

View workflow job for this annotation

GitHub Actions / TDBX Vale rules

[vale] reported by reviewdog 🐶 [MongoDB.Time24h2Digits] Show the hours, minutes, and seconds with two digits each, even if the leading digit is 0 ('1:30'). Raw Output: {"message": "[MongoDB.Time24h2Digits] Show the hours, minutes, and seconds with two digits each, even if the leading digit is 0 ('1:30').", "location": {"path": "source/interact-data/atlas-search-tutorial.txt", "range": {"start": {"line": 307, "column": 34}}}, "severity": "ERROR"}

To submit a query, add a term or phrase in the search bar then
click the :guilabel:`Search` button. The following image depicts
the search results for the term ``"outdoor"``:

.. figure:: /includes/figures/atlas-search-tutorial-render.png
:alt: The rendered Search results

The search results depend on the documents in your
database. As the complexity of your data increases, you might need
to perform more advanced queries to narrow results. To learn more
about different Atlas Search queries and view examples, see the
:atlas:`Query Reference </atlas-search/query-ref/>` in the Atlas
documentation.

Conclusion
----------

In this tutorial, you learned how to integrate the Atlas Search feature
into a Rails application. This integration enhances usability and
functionality while improving user engagement.

To learn more about performing queries in {+odm+}, see the
:ref:`mongoid-interact-data` guides.
3 changes: 3 additions & 0 deletions source/quick-start-rails/next-steps.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,6 @@ Learn more about {+odm+} features from the following sections:

- :ref:`mongoid-interact-data`: Learn how to interact with your MongoDB
data by using {+odm+} models.

- :ref:`mongoid-atlas-search-rails-tutorial`: Learn how to integrate the
Atlas Search feature into your application.
Loading