Building a voice-activated movie search app powered by Amazon Lex, Lambda, and MongoDB Atlas - Part 2
Tags: aws, node, nosql, serverless
Published: 2018-02-27 21:09:54

---
title: "Building a voice-activated movie search app powered by Amazon Lex, Lambda, and MongoDB Atlas - Part  2"
published: true
tags: #aws #node #nosql #serverless
canonical_url: https://www.mongodb.com//blog/post/aws-lex-lambda-mongodb-atlas-movie-search-app-part-2
---

### Introduction

Before you read this article, take a look at [Part 1](https://www.mongodb.com/blog/post/aws-lex-lambda-mongodb-atlas-movie-search-app-part-1?utm_medium=dev-synd&utm_source=dev&utm_content=lex2&jmp=dev-ref) for a brief overview of Amazon Lex and instructions to set up our movie database with [MongoDB Atlas](https://www.mongodb.com/cloud/atlas?utm_medium=dev-synd&utm_source=dev&utm_content=lex2&jmp=dev-ref), our fully managed database service.

As a reminder, this tutorial is divided into 4 parts:

- 

[Part 1: Lex overview, demo scenario and data layer setup](https://www.mongodb.com/blog/post/aws-lex-lambda-mongodb-atlas-movie-search-app-part-1?utm_medium=dev-synd&utm_source=dev&utm_content=lex2&jmp=dev-ref)

- 

Part 2: Set up and test an Amazon Lex bot (this post)

- 

[Part 3: Deploy a Lambda function as our Lex bot fulfillment](https://www.mongodb.com/blog/post/aws-lex-lambda-mongodb-atlas-movie-search-app-part-3?utm_medium=dev-synd&utm_source=dev&utm_content=lex2&jmp=dev-ref)

In this blog post, we will set up our Lex bot in the AWS Console and verify that its basic flow works as expected. We’ll implement the business logic (which leverages MongoDB) in Part 3 of this post series.

### Amazon Lex bot setup instructions

In this section, we will go through the whole process of creating our _SearchMovies_ bot while explaining the architectural decisions I made.

After signing in into the [AWS Console](https://aws.amazon.com/console/), select the Lex service (in the Artificial Intelligence section) and press the **Create** button.

Select the **Custom bot** option and fill out the form parameters as follows:

- 

Bot name: **SearchMoviesBot**

- 

Output voice: **None**

- 

Session timeout: **5**

- 

COPPA: **No**

Press the **Create** button at the bottom of the form.

A new page appears, where you can create an intent. Press the **Create Intent** button and in the **Add intent** pop-up page, click the **Create new intent** link and enter **_SearchMovies_** in the intent name field.

In the **_Slot types_** section, add a new slot type with the following properties:

- 

Slot type name: **_MovieGenre_**

- 

Description: **_Genre of the movie (Action, Comedy, Drama…)_**

- 

Slot Resolution: **_Restrict to Slot values and Synonyms_**

- 

Values: **_All, Action, Adventure, Biography, Comedy, Crime, Drama, Romance, Thriller_**

![image alt text](https://webassets.mongodb.com/_com_assets/cms/image_0-srs3a9ixjq.png)

You can add synonyms to all these terms (which strictly match the possible values for movie genres in our sample database), but the most important one for which you will want to configure synonyms is the **_Any_** value. We will use it as a keyword to avoid filtering on movie genre in scenarios when the user cannot qualify the genre of the movie he’s looking for or wants to retrieve all the movies for a specific cast member. Of course, you can explore the movie database on your own to identify and add other movie genres I haven’t listed above. Once you’re done, press the **Save slot type** button.

Next, in the **_Slots_** section, add the following 3 slots:

1. 

**_genre_**

  1. 

Type: **_MovieGenre_**

  2. 

Prompt: **_I can help with that. What's the movie genre?_**

  3. 

Required: **_Yes_**

2. 

**_castMember_**

  1. 

Type: **_AMAZON.Actor_**

  2. 

Prompt: **_Do you know the name of an actor or actress in that movie?_**

  3. 

Required: **_Yes_**

3. 

**_year_**

  1. 

Type: **_AMAZON.FOUR\_DIGIT\_NUMBER_**

  2. 

Prompt: **_Do you know the year {castMember}'s movie was released? If not, just type 0_**

  3. 

Required: **_Yes_**

Press the **Save Intent** button and verify you have the same setup as shown in the screenshot below:

![image alt text](https://webassets.mongodb.com/_com_assets/cms/image_1-k44ww1m57n.png)

The order of the slots is important here: once the user’s first utterance has been detected to match a Lex intent, the Lex bot will (by default) try to collect the slot values from the user in the priority order specified above by using the Prompt texts for each slot. Note that you can use previously collected slot values in subsequent slot prompts, which I demonstrate in the ‘_year_’ slot. For instance, if the user answered _Angelina Jolie_ to the _castMember_ slot prompt, the _year_ slot prompt will be: _‘Do you know the year Angelina Jolie’s movie was released? If not, just type 0_

Note that it’s important that all the slots are marked **_Required_**. Otherwise, the only opportunity for the user to specify them is to mention them in the original utterance. As you will see below, we will provide such ability for Lex to identify slots right from the start, but what if the user chooses to kick off the process without mentioning any of them? If the slots aren’t required, they are by default overlooked by the Lex bot so we need to mark them _Required_ to offer the user the option to define them.

But what if the user doesn’t know the answer to those prompts? We’ve handled this case as well by defining "default" values: **_All_** for the genre slot and **_0_** for the year slot. The only mandatory parameter the bot’s user must provide is the cast member’s name; the user can restrict the search further by providing the movie genre and release year.

Last, let’s add the following sample utterances that match what we expect the user will type (or say) to launch the bot:

- 

I am looking for a movie

- 

I am looking for a ​{genre}​ movie

- 

I am looking for a movie released in ​{year}​

- 

I am looking for a ​{genre}​ movie released in ​{year}​

- 

In which movie did ​{castMember}​ play

- 

In which movie did ​{castMember}​ play in {year}

- 

In which ​{genre}​ movie did ​{castMember}​ play

- 

In which ​{genre}​ movie did ​{castMember}​ play in {year}

- 

I would like to find a movie

- 

I would like to find a movie with ​{castMember}​

Once the utterances are configured as per the screenshot below, press **_Save Intent_** at the bottom of the page and then **_Build_** at the top of the page. The process takes a few seconds, as AWS builds the deep learning model Lex will use to power our _SearchMovies_ bot.

![image alt text](https://webassets.mongodb.com/_com_assets/cms/image_2-x9mh5f359p.png)

It’s now time to test the bot we just built!

### Testing the bot

Once the build process completes, the test window automatically shows up:

![image alt text](https://webassets.mongodb.com/_com_assets/cms/image_3-aldti5086j.png)

Test the bot by typing (or saying) sentences that are close to the sample utterances we previously configured. For instance, you can type ‘_Can you help me find a movie with Angelina Jolie?_’ and see the bot recognize the sentence as a valid kick-off utterance, along with the _{castMember}_ slot value (in this case, ‘_Angelina Jolie_’). This can be verified by looking at the Inspect Response panel:

![image alt text](https://webassets.mongodb.com/_com_assets/cms/image_4-vg1y388asj.png)

At this point, the movie genre hasn’t been specified yet, so Lex prompts for it (since it’s the first required slot). Once you answer that prompt, notice that Lex skips the second slot (_{castMember}_) since it already has that information.

Conversely, you can test that the _‘Can you help me find a comedy movie with angelina jolie?’_ utterance will immediately prompt the user to fill out the {year} slot since both the _{castMember}_ and _{genre}_ values were provided in the original utterance:

![image alt text](https://webassets.mongodb.com/_com_assets/cms/image_5-tci29y4wt9.png)

An important point to note here is that enumeration slot types (such as our _MovieGenre_ type) are not case-sensitive. This means that both "comedy" and “coMeDy” will resolve to “Comedy”. This means we will be able to use a regular index on the Genres property of our movies collection (as long as our enumeration values in Lex match the Genres case in our database).

However, the _AMAZON.Actor_ type is case sensitive - for instance, "_angelina jolie_" and “_Angelina Jolie_” are 2 distinct values for Lex. This means that we must define a [case-insensitive index](https://docs.mongodb.com/manual/core/index-case-insensitive?jmp=adref) on the **Cast** property (don’t worry, there is already such an index, called ‘Cast\_1’ in our sample movie database). Note that in order for queries to use that case-insensitive index, we’ll have to make sure our find() query specifies the same [collation](https://docs.mongodb.com/manual/reference/collation?utm_medium=dev-synd&utm_source=dev&utm_content=lex2&jmp=dev-ref) as the one used to create the index (locale=’en’ and strength=1). But don’t worry for now: I’ll make sure to point it out again in Part 3 when we review the code of our chat’s business logic (in the Lambda function we’ll deploy).

### Summary

In this blog post, we created the SearchMovies Lex bot and tested its flow. More specifically, we:

- 

Created a custom Lex slot type (MovieGenre)

- 

Configured intent slots

- 

Defined sample utterances (some of which use our predefined slots)

- 

Tested our utterances and the specific prompt flows each of them starts

We also identified the case sensitivity of a built-in Lex slot that adds a new index requirement on our database.

In [Part 3](https://www.mongodb.com/blog/post/aws-lex-lambda-mongodb-atlas-movie-search-app-part-3?utm_medium=dev-synd&utm_source=dev&utm_content=lex2&jmp=dev-ref), we’ll get to the meat of this Lex blog post series and deploy the Lambda function that will allow us to complete our bots’ intended action (called ‘fulfillment’ in the Lex terminology).

Meanwhile, I suggest the following readings to further your knowledge of Lex and MongoDB:

- 

[Lex built-in slot types](https://developer.amazon.com/docs/custom-skills/slot-type-reference.html)

- 

[Case-insensitive indexes](https://docs.mongodb.com/manual/core/index-case-insensitive?jmp=adref)

_About the Author - **Raphael Londner** _

Raphael Londner is a Principal Developer Advocate at MongoDB, focused on cloud technologies such as Amazon Web Services, Microsoft Azure and Google Cloud Engine. Previously he was a developer advocate at Okta as well as a startup entrepreneur in the identity management space. You can follow him on Twitter at _**[@rlondner](https://www.twitter.com/rlondner)**_.