MongoFlix — интерактивная демонстрация MongoDB Atlas Search, MongoDB App Services, GraphQL и многого другого.
Вот что мы построим!
Также доступно в Службах приложений в виде статического сайта!
Конечно, вы можете клонировать репозиторий и запустить проект локально npm install && npm run build
. Кроме того, вы можете открыть проект в браузере без необходимости установки на свой компьютер.
Откройте проект в прямом эфире на StackBlitz:
Дублируйте файл .env.local.example-add-app-id-here
и назовите его: .env.local
. Вам нужно будет изменить значение <APP_ID>
на идентификатор вашего приложения MongoDB App Services, которое будет создано на более позднем этапе. Вам также необходимо обновить значение NEXT_PUBLIC_REALM_BASE_URL
, если у вас есть другой базовый URL-адрес для вашего приложения MongoDB App Services. Это значение будет зависеть от региона развертывания вашего приложения MongoDB App Services.
Чтобы продолжить работу с демонстрацией, вам нужно будет создать кластер MongoDB Atlas и загрузить в него образец набора данных. Пожалуйста, создайте учетную запись в MongoDB Atlas и следуйте инструкциям. Если вы используете Atlas впервые, вам потребуется создать организацию и проект. После завершения настройки учетной записи вы увидите пользовательский интерфейс Atlas . Если у вас нет кластера, нажмите кнопку «Построить базу данных» .
В следующем диалоговом окне выберите «Общий» и нажмите «Создать» . На следующем экране представлен интерфейс для настройки кластера.
Если вы выберете регион, отличный от Франкфурта, вам потребуется обновить конечную точку в приложении в .env.local
чтобы она соответствовала региону.
Вот настройки кластера:
AWS, Frankfurt (eu-central-1)
MO Sandbox (Shared RAM, 512 MB Storage)
Cluster0
После того как ваш кластер будет развернут в выбранном вами регионе, вам нужно будет загрузить образец набора данных в ваш кластер. Нажмите на меню из трех точек в верхнем заголовке карточки кластера. Нажмите «Загрузить образец набора данных» . Нажмите кнопку «Загрузить набор выборочных данных» в наложении, чтобы начать процесс. (Это должно занять около 5-10 минут. ☕️ ?)
Щелкните имя кластера, чтобы открыть его. В своем кластере в Atlas щелкните вкладку «Поиск» . Нажмите кнопку «Создать индекс поиска», чтобы создать индекс.
sample_mflix
и выберите movies
.default
и вставьте следующий JSON.{
"mappings" : {
"dynamic" : true ,
"fields" : {
"title" : [
{
"dynamic" : true ,
"type" : " document "
},
{
"type" : " autocomplete "
}
]
}
}
}
Создание индекса должно занять меньше минуты. Давайте проверим это, чтобы убедиться, что это работает. Продолжая работать на вкладке «Поиск» , нажмите кнопку «Запрос» рядом с вновь созданным индексом. Введите следующий запрос, чтобы найти все фильмы, содержащие текстовое time
в любых текстовых значениях.
{ "$search" : { "text" : " time travel " } }
В пользовательском интерфейсе Atlas щелкните вкладку «Службы приложений» вверху. Если вы используете Службы приложений впервые, вы увидите диалоговое окно с дополнительными инструкциями. Вы можете смело выбрать «Создать собственное приложение» и нажать « Далее» . Информация должна заполняться автоматически. Для простоты обязательно используйте одно и то же имя.
В следующем диалоговом окне настройте имя приложения App Services, подключите его к вновь созданному кластеру и выберите локальную (один регион) модель развертывания. Предпочтительнее использовать регион, ближайший к региону вашего кластера.
Чтобы создать приложение, нажмите «Создать приложение служб приложений» .
Подсказка: теперь, когда приложение создано, вы можете обновить файл .env.local
, включив в него значение App ID из вашего приложения App Services.
На левой боковой панели пользовательского интерфейса Atlas в разделе «Доступ к данным » нажмите «Аутентификация» . Как вы видите, Службы приложений предоставляют множество методов аутентификации, для этой демонстрации мы будем использовать Anonymous . Нажмите кнопку «Изменить» и установите флажок «ВКЛ » для этого метода аутентификации.
На левой боковой панели пользовательского интерфейса Atlas в разделе «Доступ к данным » нажмите «Правила» . Правила предоставляют вам множество способов ограничить и настроить доступ к данным для каждой коллекции и роли пользователя, вплоть до уровня документа. В этой демонстрации мы разрешим всем пользователям только read
все документы в коллекции фильмов. Службы приложений предоставляют шаблоны для многих сценариев, и мы будем использовать шаблон «Пользователи могут только читать все данные» .
На левой боковой панели пользовательского интерфейса Atlas в разделе «Доступ к данным » нажмите «Схема» . Схема определяет структуры и типы данных для документов в каждой коллекции в базах данных. Выберите коллекцию фильмов в базе данных sample_mflix . Нажмите кнопку «Создать схему». Выберите только коллекцию фильмов , оставьте размер выборки по умолчанию и нажмите кнопку «Создать схему» . Это также создаст все необходимые типы и запросы для схемы GraphQL . Его можно сразу использовать для доступа к данным через конечную точку GraphQL, управляемую службами приложений.
Нажмите кнопку «Просмотреть черновик и развернуть» в верхней части страницы и разверните изменения.
Подсказка: теперь, когда схема создана, вы можете обновить файл .env.local
, включив в него следующий базовый URL-адрес из вашего приложения служб приложений.
Давайте проверим, как на самом деле работает GraphQL. На вкладке GraphQL в редакторе GraphQL вставьте следующий фрагмент кода, чтобы протестировать сгенерированную схему.
query {
movie ( query : { title : " The Godfather " }) {
_id
title
metacritic
num_mflix_comments
fullplot
}
}
Теперь, имея правильные правила и схему, мы можем приступить к созданию функций для приложения. Для первой функции мы создадим функцию, которая будет возвращать список фильмов, соответствующих поисковому запросу по названию. Он будет использовать наш динамический индекс, созданный на предыдущем шаге, с функцией автозаполнения. Это позволяет нам обеспечить автозаполнение и нечеткий поиск по наклонам фильма в строке поиска внешнего приложения.
На левой боковой панели пользовательского интерфейса Atlas в разделе «Сборка » нажмите «Функции» . Функции позволяют выполнять серверную логику в службах приложений, интегрируя данные из подключенного кластера. Имея в своем распоряжении Aggregation Framework , вы можете создавать очень мощные агрегаты даже без драйвера.
Нажмите кнопку «Создать новую функцию» и введите autocompleteTitle
в качестве имени функции.
Теперь перейдите на вкладку «Редактор функций» .
Вставьте следующий код в редактор функций :
exports = async ( title ) => {
const collection = context . services . get ( "mongodb-atlas" ) . db ( "sample_mflix" ) . collection ( "movies" ) ;
return await collection
. aggregate ( [
{
$search : {
autocomplete : {
path : "title" ,
query : title ,
fuzzy : { maxEdits : 1 } ,
} ,
} ,
} ,
{
$project : {
title : 1 ,
} ,
} ,
{
$limit : 10 ,
} ,
] )
. toArray ( ) ;
} ;
Нажмите кнопку «Сохранить черновик», чтобы сохранить функцию.
Мы хотим использовать функцию автозаполнения в нашей схеме GraphQL. Для этого нам нужно создать собственный преобразователь. Пользовательские преобразователи позволяют нам определять собственные запросы и мутации для нашей схемы GraphQL, поддерживаемые функциями, созданными в службах приложений.
На левой боковой панели пользовательского интерфейса Atlas в разделе «Сборка » нажмите GraphQL . Перейдите на вкладку «Пользовательские резольверы» и нажмите кнопку «Добавить пользовательский резольвер» . В качестве имени поля GraphQL введите autocompleteTitle
, в качестве родительского типа выберите Query , а в качестве имени функции выберите вновь созданную функцию autocompleteTitle
.
Тип ввода определяет тип данных, которые будут отправлены в API GraphQL в качестве входных данных для этого преобразователя. Тип возвращаемого значения определяет тип данных, возвращаемых API. Мы отправим строку в качестве входных данных и ожидаем список объектов фильма в качестве выходных данных.
Scalar Type
, String
Existing Type (List)
, [Movie]
Нажмите кнопку «Сохранить черновик», чтобы сохранить пользовательский преобразователь.
Нажмите кнопку «Просмотреть черновик и развернуть» в верхней части страницы и разверните изменения.
Теперь, когда вы выполнили первую настройку функции, найдите время, чтобы протестировать приложение, ввести названия фильмов в строку поиска и просмотреть результаты автозаполнения.
Теперь, когда есть функция автозаполнения, мы можем создать новую функцию для выделения и оценки. Эта функция вернет список фильмов, соответствующих поисковому запросу по названию, выбранным жанрам и стране, в которой был произведен определенный фильм. Кроме того, он вернет основные моменты и результаты поиска по результатам. Выделение содержит точную подстроку в заголовке и строки графика, содержащие соответствующий поисковый запрос. Это позволит нам выделить найденные поисковые запросы в пользовательском интерфейсе.
Подобно предыдущей функции, мы создадим новую функцию для выделения моментов и оценки.
На левой боковой панели пользовательского интерфейса Atlas в разделе «Сборка » нажмите «Функции» . Нажмите кнопку «Создать новую функцию» и введите filteredMovies
в качестве имени функции.
Теперь перейдите на вкладку «Редактор функций» .
Вставьте следующий код в редактор функций :
exports = async ( input ) => {
const collection = context . services . get ( "mongodb-atlas" ) . db ( "sample_mflix" ) . collection ( "movies" ) ;
const { term , genres , countries } = input ;
const searchShould = [ ] ;
const searchMust = [ ] ;
if ( term . length > 0 ) {
const termStage = {
autocomplete : {
path : "title" ,
query : term ,
fuzzy : { maxEdits : 1.0 } ,
score : {
boost : {
path : "imdb.rating" ,
undefined : 1 ,
} ,
} ,
} ,
} ;
searchMust . push ( termStage ) ;
const plotStage = {
text : {
query : term ,
path : "plot" ,
} ,
} ;
searchShould . push ( plotStage ) ;
}
if ( genres . length > 0 ) {
const genresStage = {
text : {
query : genres ,
path : "genres" ,
} ,
} ;
searchMust . push ( genresStage ) ;
}
if ( countries . length > 0 ) {
const countryStage = {
text : {
query : countries ,
path : "countries" ,
} ,
} ;
searchMust . push ( countryStage ) ;
}
const searchQuery = [
{
$search : {
compound : {
should : searchShould ,
must : searchMust ,
} ,
highlight : { path : [ "title" , "genres" , "countries" , "plot" ] } ,
} ,
} ,
{
$project : {
_id : 1 ,
title : 1 ,
poster : 1 ,
cast : 1 ,
directors : 1 ,
plot : 1 ,
fullplot : 1 ,
year : 1 ,
genres : 1 ,
countries : 1 ,
imdb : 1 ,
score : { $meta : "searchScore" } ,
highlights : { $meta : "searchHighlights" } ,
} ,
} ,
{ $limit : 20 } ,
] ;
return await collection . aggregate ( searchQuery ) . toArray ( ) ;
} ;
На левой боковой панели пользовательского интерфейса Atlas в разделе «Сборка » нажмите GraphQL . Перейдите на вкладку «Пользовательские резольверы» и нажмите кнопку «Добавить собственный резольвер» . В качестве имени поля GraphQL введите filteredMovies
, в качестве родительского типа выберите Query , а в качестве имени функции выберите вновь созданную функцию filteredMovies
.
Мы отправим строку в качестве входных данных и ожидаем на выходе список пользовательских объектов фильма, содержащий оценки и основные моменты для каждого фильма.
Custom Type
{
"type" : " object " ,
"title" : " FilteredMoviesInput " ,
"properties" : {
"term" : {
"bsonType" : " string "
},
"genres" : {
"bsonType" : " array " ,
"items" : {
"bsonType" : " string "
}
},
"countries" : {
"bsonType" : " array " ,
"items" : {
"bsonType" : " string "
}
}
}
}
Custom Type
{
"items" : {
"bsonType" : " object " ,
"properties" : {
"_id" : {
"bsonType" : " objectId "
},
"cast" : {
"bsonType" : " array " ,
"items" : {
"bsonType" : " string "
}
},
"countries" : {
"bsonType" : " array " ,
"items" : {
"bsonType" : " string "
}
},
"directors" : {
"bsonType" : " array " ,
"items" : {
"bsonType" : " string "
}
},
"fullplot" : {
"bsonType" : " string "
},
"genres" : {
"bsonType" : " array " ,
"items" : {
"bsonType" : " string "
}
},
"highlights" : {
"bsonType" : " array " ,
"items" : {
"bsonType" : " object " ,
"properties" : {
"path" : {
"bsonType" : " string "
},
"score" : {
"bsonType" : " double "
},
"texts" : {
"bsonType" : " array " ,
"items" : {
"bsonType" : " object " ,
"properties" : {
"type" : {
"bsonType" : " string "
},
"value" : {
"bsonType" : " string "
}
}
}
}
}
}
},
"imdb" : {
"bsonType" : " object " ,
"properties" : {
"id" : {
"bsonType" : " int "
},
"rating" : {
"bsonType" : " double "
},
"votes" : {
"bsonType" : " int "
}
}
},
"plot" : {
"bsonType" : " string "
},
"poster" : {
"bsonType" : " string "
},
"score" : {
"bsonType" : " double "
},
"title" : {
"bsonType" : " string "
},
"year" : {
"bsonType" : " int "
}
}
},
"title" : " FilteredMovies " ,
"type" : " array "
}
Нажмите кнопку «Сохранить черновик», чтобы сохранить пользовательский преобразователь.
Нажмите кнопку «Просмотреть черновик и развернуть» в верхней части страницы и разверните изменения.
Теперь, когда настроена функция «Основные моменты», найдите время протестировать приложение, введите названия некоторых фильмов в строку поиска, прокрутите список результатов и убедитесь, что нечетко совпадающий поисковый запрос выделен в названии фильма и коротком сюжете, если есть совпадение. .
Фасеты открывают множество эффективных вариантов использования для группировки результатов поиска. Следующая функция показывает, как запустить запрос Atlas Search, чтобы получить результаты, сгруппированные по значениям для жанров каждого фильма в коллекции фильмов , включая количество для каждой из этих групп.
В своем кластере в Atlas на вкладке «Поиск » создайте новый индекс с именами facets
и следующим JSON для коллекции фильмов .
{
"mappings" : {
"dynamic" : false ,
"fields" : {
"genres" : [
{
"dynamic" : true ,
"type" : " document "
},
{
"type" : " stringFacet "
}
],
"year" : [
{
"dynamic" : true ,
"type" : " document "
},
{
"representation" : " int64 " ,
"type" : " number "
}
]
}
}
}
Теперь, когда индекс создан, в пользовательском интерфейсе Atlas щелкните вкладку Службы приложений . Нажмите «Приложение-0» в пользовательском интерфейсе. На левой боковой панели пользовательского интерфейса Atlas в разделе «Сборка » нажмите «Функции» . Нажмите кнопку «Создать новую функцию» и введите facetsGenres
в качестве имени функции.
Теперь перейдите на вкладку «Редактор функций» .
Вставьте следующий код в редактор функций :
exports = async ( arg ) => {
const collection = context . services . get ( "mongodb-atlas" ) . db ( "sample_mflix" ) . collection ( "movies" ) ;
return await collection
. aggregate ( [
{
$searchMeta : {
index : "facets" ,
facet : {
operator : {
range : {
path : "year" ,
gte : 1900 ,
} ,
} ,
facets : {
genresFacet : {
type : "string" ,
path : "genres" ,
} ,
} ,
} ,
} ,
} ,
] )
. toArray ( ) ;
} ;
На левой боковой панели пользовательского интерфейса Atlas в разделе «Сборка » нажмите GraphQL . Перейдите на вкладку «Пользовательские резольверы» и нажмите кнопку «Добавить пользовательский резольвер» . В качестве имени поля GraphQL введите facetsGenres
, в качестве родительского типа выберите Query , а в качестве имени функции выберите вновь созданную функцию facetsGenres
.
Мы не будем отправлять входные данные в этот запрос и ожидаем список пользовательских объектов, представляющих аспекты для каждого жанра, содержащий количество фильмов для каждого жанра.
None
Custom Type
{
"title" : " GenresMeta " ,
"type" : " array " ,
"items" : {
"bsonType" : " object " ,
"properties" : {
"count" : {
"bsonType" : " double "
},
"facet" : {
"bsonType" : " object " ,
"properties" : {
"genresFacet" : {
"bsonType" : " object " ,
"properties" : {
"buckets" : {
"bsonType" : " array " ,
"items" : {
"bsonType" : " object " ,
"properties" : {
"_id" : {
"bsonType" : " string "
},
"count" : {
"bsonType" : " double "
}
}
}
}
}
}
}
}
}
}
}
Нажмите кнопку «Сохранить черновик», чтобы сохранить пользовательский преобразователь.
Нажмите кнопку «Просмотреть черновик и развернуть» в верхней части страницы и разверните изменения.
Теперь, настроив фасеты, протестируйте приложение и откройте раскрывающийся список «Жанры» . Обратите внимание, что теперь помимо каждого жанра есть число, обозначающее общее количество фильмов этого жанра.
Хостинг служб приложений MongoDB позволяет вам размещать, управлять и обслуживать статические медиафайлы и файлы документов вашего приложения. Вы можете использовать хостинг для хранения отдельных частей контента или для загрузки и обслуживания всего клиентского приложения.
Наше внешнее приложение содержит все необходимые вызовы API GraphQL в службах приложений. Мы можем экспортировать все интерфейсное приложение как статический сайт и разместить его в службах приложений MongoDB.
Для этого вам необходимо выполнить следующий код в корневой папке проекта. Убедитесь, что у вас установлены зависимости.
npm install
а затем создайте и экспортируйте сайт с помощью сценария npm, используя nextjs.
npm run build && npm run export
Это создаст папку с out
в корневой папке проекта.
В пользовательском интерфейсе MongoDB Atlas на вкладке Службы приложений . На левой боковой панели пользовательского интерфейса Atlas в разделе «Управление » нажмите «Хостинг» . Нажмите кнопку «Включить хостинг» . Перетащите содержимое папки out
вкладку «Хостинг» , чтобы загрузить все файлы.
Нажмите кнопку «Просмотреть черновик и развернуть» в верхней части страницы и разверните изменения.
Перейдите на вкладку «Настройки» , скопируйте домен служб приложений , вставьте его в выбранный вами браузер и нажмите Enter, чтобы просмотреть сайт. ?