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
C#
plus
Sign in to follow topics
MongoDB Developer Centerchevron-right
Developer Topicschevron-right
Languageschevron-right
C#chevron-right

MongoDB Atlas Search with .NET Blazor for Full-Text Search

Luce Carter6 min read • Published Feb 01, 2024 • Updated Feb 01, 2024
.NETC#
FULL APPLICATION
Facebook Icontwitter iconlinkedin icon
Rate this tutorial
star-empty
star-empty
star-empty
star-empty
star-empty
Imagine being presented with a website with a large amount of data and not being able to search for what you want. Instead, you’re forced to sift through piles of results with no end in sight.
That is, of course, the last thing you want for yourself or your users. So in this tutorial, we’ll see how you can easily implement search with autocomplete in your .NET Blazor application using MongoDB Atlas Search.
Atlas Search is the easiest and fastest way to implement relevant searches into your MongoDB Atlas-backed applications, making it simpler for developers to focus on implementing other things.

Prerequisites

In order to follow along with this tutorial, you will need a few things in place before you start:
  • An IDE or text editor that can support C# and Blazor for the most seamless development experience, such as Visual Studio, Visual Studio Code with the C# DevKit Extension installed, and JetBrains Rider.
  • An Atlas M0 cluster, our free forever tier, perfect for development.
  • The sample dataset loaded into the cluster.
  • Your cluster connection string for use in your application settings later on.
  • A fork of the GitHub repo that we will be adding search to.
Once you have forked and then cloned the repo and have it locally, you will need to add your connection string into appsettings.Development.json and appsettings.json in the placeholder section in order to connect to your cluster when running the project.
If you don’t want to follow along, the repo has a branch called “full-text-search” which has the final result implemented.

Creating Atlas Search indexes

Before we can start adding Atlas Search to our application, we need to create search indexes inside Atlas. These indexes enable full-text search capabilities on our database. We want to specify what fields we wish to index.
Atlas Search does support dynamic indexes, which apply to all fields and adapt to any document shape changes. But for this tutorial, we are going to add a search index for a specific field, “title.”
  1. Inside Atlas, click “Browse Collections” to open the data explorer to view your newly loaded sample data.
  2. Select the “Atlas Search” tab at the top.
  3. Click the green “Create Search Index” button to load the index creation wizard.
  4. Select Visual Editor and then click “Next.”
  5. Give your index a name. What you choose is up to you.
  6. For “Database and Collection,” select “sample_mflix” to expand the database and select the “movies” collection. Then, click “Next.”
  7. In the final review section, click the “Refine Your Index” button below the “Index Configurations” table as we want to make some changes.
  8. Click “+ Add Field Mapping” about halfway down the page.
  9. In “Field Name,” search for “title.”
  10. For “Data Type,” select “Autocomplete.” This is because we want to have autocomplete available in our application so users can see results as they start typing.
  11. Click the “Add” button in the bottom right corner.
  12. Click “Save” and then “Create Search Index.”
Title field mapped as autocomplete
After a few minutes, the search index will be set up and the application will be ready to be “searchified.”
If you prefer to use the JSON editor to simply copy and paste, you can use the following:
1{
2 "mappings": {
3 "dynamic": true,
4 "fields": {
5 "title": {
6 "type": "autocomplete"
7 }
8 }
9 }
10}

Implementing backend functionality

Now the database is set up to support Atlas Search with our new indexes, it's time to update the code in the application to support search. The code has an interface and service for talking to Atlas using the MongoDB C# driver which can be found in the Services folder.

Adding a new method to IMongoDBService

First up is adding a new method for searching to the interface.
Open IMongoDBService.cs and add the following code:
1public IEnumerable<Movie> MovieSearchByText (string textToSearch);
We return an IEnumerable of movie documents because multiple documents might match the search terms.

Implementing the method in MongoDBService

Next up is adding the implementation to the service.
  1. Open MongoDBService.cs and paste in the following code:
1public IEnumerable<Movie> MovieSearchByText(string textToSearch)
2{
3// define fuzzy options
4 SearchFuzzyOptions fuzzyOptions = new SearchFuzzyOptions()
5 {
6 MaxEdits = 1,
7 PrefixLength = 1,
8 MaxExpansions = 256
9 };
10
11 // define and run pipeline
12 var movies = _movies.Aggregate().Search(Builders<Movie>.Search.Autocomplete(movie => movie.Title,
13 textToSearch, fuzzy: fuzzyOptions), indexName: "title").Project<Movie>(Builders<Movie>.Projection
14 .Exclude(movie => movie.Id)).ToList();
15 return movies;
16}
Replace the value for indexName with the name you gave your search index.
Fuzzy search allows for approximate matching to a search term which can be helpful with things like typos or spelling mistakes. So we set up some fuzzy search options here, such as how close to the right term the characters need to be and how many characters at the start that must exactly match.
Atlas Search is carried out using the $search aggregation stage, so we call .Aggregate() on the movies collection and then call the ``Search``` method.
We then pass a builder to the search stage to search against the title using our passed-in search text and the fuzzy options from earlier.
The .Project() stage is optional but we’re going to include it because we don’t use the _id field in our application. So for performance reasons, it is always good to exclude any fields you know you won’t need to be returned.
You will also need to make sure the following using statements are present at the top of the class for the code to run later:
1using SeeSharpMovies.Models;
2using MongoDB.Driver;
3using MongoDB.Driver.Search;
Just like that, the back end is ready to accept a search term, search the collection for any matching documents, and return the result.

Implementing frontend functionality

Now the back end is ready to accept our searches, it is time to implement it on the front end so users can search. This will be split into two parts: the code in the front end for talking to the back end, and the search bar in HTML for typing into.
This application uses razor pages which support having code in the front end. If you look inside Home.razor in the Components/Pages folder, you will see there is already some code there for requesting all movies and pagination.
  1. Inside the @code block, underneath the existing variables, add the following code:
1string searchTerm;
2Timer debounceTimer;
3int debounceInterval = 200;
As expected, there is a string variable to hold the search term, but the other two values might not seem obvious. In development, where you are accepting input and then calling some kind of service, you want to avoid calling it too often. So you can implement something called debounce which handles that. You will see that implemented later but it uses a timer and an interval — in this case, 200 milliseconds.
  1. Add the following code after the existing methods:
1private void SearchMovies()
2 {
3 if (string.IsNullOrWhiteSpace(searchTerm))
4 {
5 movies = MongoDBService.GetAllMovies();
6 }
7 else
8 {
9 movies = MongoDBService.MovieSearchByText(searchTerm);
10 }
11 }
12
13
14void DebounceSearch(object state)
15 {
16 if (string.IsNullOrWhiteSpace(searchTerm))
17 {
18 SearchMovies();
19 }
20 else
21 {
22 InvokeAsync(() =>
23 {
24 SearchMovies();
25 StateHasChanged();
26 });
27 }
28 }
29
30void OnSearchInput(ChangeEventArgs e)
31 {
32 searchTerm = e.Value.ToString();
33 debounceTimer?.Dispose();
34 debounceTimer = new Timer(DebounceSearch, null, debounceInterval, Timeout.Infinite);
35 }
SearchMovies: This method handles an empty search box as trying to search on nothing will cause it to error. So if there is nothing in the search box, it fetches all movies again. Otherwise, it calls the backend method we implemented previously to search by that term.
DebounceSearch: This calls search movies and if there is a search term available, it also tells the component that the stage has changed.
OnSearchInput: This will be called later by our search box but this is an event handler that says that when there is a change event, set the search term to the value of the box, reset the debounce timer, and start it again from the timer interval, passing in the DebounceSearch method as a callback function.
Now we have the code to smoothly handle receiving input and calling the back end, it is time to add the search box to our UI.
Adding the search bar is really simple. We are going to add it to the header component already present on the home page.
After the link tag with the text “See Sharp Movies,” add the following HTML:
1<div class="form-inline search-bar">
2 <input class="form-control mr-sm-2"
3 type="search" placeholder="Search"
4 aria-label="Search"
5 @oninput="OnSearchInput" @bind="searchTerm">
6</div>

Testing the search functionality

Now we have the backend code available and the front end has the search box and a way to send the search term to the back end, it's time to run the application and see it in action.
Run the application, enter a search term in the box, and test the result.
Animation showing searching the movies

Summary

Excellent! You now have a Blazor application with search functionality added and a good starting point for using full-text search in your applications going forward.
If you want to learn more about Atlas Search, including more features than just autocomplete, you can take an amazing Atlas Search workshop created by my colleague or view the [docs]https://mongodb.prakticum-team.ru/docs/manual/text-search/). If you have questions or feedback, join us in the Community Forums.
Top Comments in Forums
There are no comments on this article yet.
Start the Conversation

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

MongoDB Geospatial Queries in C#


May 12, 2022 | 11 min read
Article

How to Use Realm Effectively in a Xamarin.Forms App


Sep 09, 2024 | 18 min read
Tutorial

Saving Data in Unity3D Using PlayerPrefs


Sep 09, 2024 | 11 min read
Tutorial

Using Polymorphism with MongoDB and C#


Apr 30, 2024 | 6 min read
Table of Contents