Lesson 5: Tune the Search Index to Return Results that Start with the Query Phrase / Learn

Video Transcript (English)

Welcome! Our autocomplete feature is coming along nicely, but let’s explore another edge case that we might want to account for.

In this lesson, you’ll learn how to ensure all results start with the query phrase. We’ll determine whether the trade-offs are worth it for our movie catalog app, and then go over the next steps for implementing autocomplete in an application.

There’s a lot to cover, so let’s get started.

First, let’s go back to one of our earlier examples and query for the movie Star Wars using the autocomplete operator.

Looking at our results, we see that every title has “Star Wars” in sequential order, which is what we want. Currently, our query phrase “star wars” can be either at the beginning, middle, or end of the title.

But what if we only want movies that begin with star wars?

One way to do this is by updating our search index to use the keyword analyzer. This will ensure that each result begins with the query phrase “star wars”.

To fully understand why this works, let’s take a look at what’s happening to our tokens.

Under the hood, the keyword analyzer is tokenizing the entire input as a single token.

Then that token gets sent to the tokenizer, which further tokenizes the query.

Given that our maxGrams is set to seven, the resulting tokens end up being: “Star”, “Star {SPACE}”, “Star W”, and finally “Star W-a”. Once we arrive at our maxGrams, tokenization stops, since the keyword analyzer only gives one token.

Looking at the sub-tokens, it appears that a large portion of our input string was not tokenized.

Keep in mind that when the query string is longer than maxGrams the result set may not be the best.

One option is to increase maxGrams however that will also increase the size of the index which can potentially degrade performance.

Notice that this is a bit different from the standard analyzer, which creates tokens for each word in the string. Those tokens are then further broken down into sub-tokens based on the tokenization strategy.

Now that we’ve updated our index, let’s run the query again.

Looks like it worked! Every title starts with “Star Wars”

Using the keyword analyzer can be a nice workaround for making sure our results start with the query phrase. But it does come with some trade-offs when using it with autocomplete.

First, when using the keyword analyzer with autocomplete, the end user needs to know exactly what they want to search for.

Next, if foldDiacritics is set to false when using the keyword analyzer, queries become case sensitive.

This is because when foldDiacritics is set to true, it acts like a filter that normalizes the string input.

Finally, if the query phrase or search term is longer than the maxGrams, the results may not be what you expect.

To account for any possible number of tokens for every movie title in our catalog, we would need to set our maxGrams value to a large number.

With these limitations in mind, we’ll forgo using the keyword analyzer and use the standard analyzer instead. After all, when searching for movies, it’s not crucial for the title to begin with the query phrase.

Nice work! At this point, we’ve covered a few ways that we can tune the autocomplete functionality for our movie catalog app.

So what’s next? We can’t expect our users to write their own aggregation search stages to find the movie they’re interested in.

As it turns out, MongoDB has us covered with Atlas App Services.

From here, we can create a simple REST API that receives the user’s input and issues the database query.

With autocomplete, every time we add a new character to our search terms, the result set is updated.

This has the potential of getting out of hand with the amount of requests being sent back and forth between the server and client.

One way to handle this is client-side buffering, where a query is issued only after user input stops for a certain number of seconds.

For instance, if a user is entering “Star Wars”, we could make it so the POST request isn’t called until the user stops typing for a second.

With this setup, users of our app can search for any movie they want with a little help from autocomplete.

Great work! Let’s take a moment to recap.

First, you learned that we can use the keyword analyzer to ensure our results start with the query phrase.

You also learned that this approach has some limitations.

First, the query must be an exact match.

Next, the query will become case-sensitive if foldDiacritics is set to false.

And finally, if the query phrase is longer than the maxGrams, the results may not be what you expect.

See you next time!