MongoFlix - MongoDB Atlas 搜索、MongoDB 应用服务、GraphQL 等的交互式演示。
这就是我们要建造的!
还可以在应用程序服务上作为静态站点使用!
您当然可以克隆存储库并在本地运行项目npm install && npm run build
。或者,您可以在浏览器中打开该项目,而无需在计算机上进行任何安装。
在 StackBlitz 上实时打开项目:
复制文件.env.local.example-add-app-id-here
并将其命名为: .env.local
。您需要将<APP_ID>
值更改为 MongoDB App Services 应用程序的应用程序 ID,该应用程序将在稍后的步骤中创建。如果您的 MongoDB App Services 应用程序有不同的基本 URL,您还必须更新NEXT_PUBLIC_REALM_BASE_URL
值。该值将取决于 MongoDB App Services 应用程序的部署区域。
要完成演示,您需要创建一个 MongoDB Atlas 集群并将示例数据集加载到集群中。请在 MongoDB Atlas 上创建一个帐户并按照说明进行操作。如果这是您第一次使用 Atlas,您将需要创建一个组织和一个项目。完成帐户设置后,您将看到Atlas UI 。如果您没有任何集群,请单击“构建数据库”按钮。
在以下对话框中选择“共享”并单击“创建” 。以下屏幕将提供配置集群的界面。
如果您选择法兰克福以外的区域,则需要更新.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 UI 中,单击顶部的“应用程序服务”选项卡。如果您是第一次使用应用服务,您将看到一个包含附加说明的对话框。您可以安全地选择“构建您自己的应用程序” ,然后单击“下一步” 。该信息应自动填充。为简单起见,请确保使用相同的名称。
在以下对话框中,设置应用程序服务应用程序的名称,将其连接到新创建的集群并选择本地(单区域)部署模型。最好使用最接近集群区域的区域。
要创建应用程序,请单击创建应用程序服务应用程序。
提示:现在创建应用程序后,您可以更新.env.local
文件以包含应用程序服务应用程序中的应用程序 ID值。
在 Atlas UI 左侧栏的“数据访问”中,单击“身份验证” 。如您所见,应用服务提供了许多身份验证方法,我们将在此演示中使用匿名。单击“编辑”按钮并将此身份验证方法的复选框设置为“开” 。
在 Atlas UI 左侧栏的“数据访问”中,单击“规则” 。规则为您提供了多种方法来限制和配置每个集合和用户角色的数据访问,深入到文档级别。对于此演示,我们将允许所有用户仅read
电影集合中的所有文档。应用服务为许多场景提供了模板,我们将使用用户只能读取所有数据模板。
在 Atlas UI 左侧栏的“数据访问”中,单击“架构” 。架构定义数据库中每个集合中文档的数据结构和类型。选择sample_mflix数据库中的电影集合。单击生成架构按钮。仅选择电影集合,将采样大小保留为默认值,然后单击“生成架构”按钮。这还将生成GraphQL模式的所有必需类型和查询。可以立即使用它通过应用服务管理的 GraphQL 端点访问数据。
单击页面顶部的“查看草稿和部署”按钮并部署您的更改。
提示:现在生成架构后,您可以更新.env.local
文件以包含应用服务应用程序中的以下基本 URL。
让我们测试一下 GraphQL 的实际工作原理。在GraphQL选项卡的 GraphQL 编辑器中粘贴以下代码片段以测试生成的方案。
query {
movie ( query : { title : " The Godfather " }) {
_id
title
metacritic
num_mflix_comments
fullplot
}
}
现在有了正确的规则和架构,我们就可以开始为应用程序创建函数了。对于第一个功能,我们将创建一个函数,该函数将返回与标题搜索词匹配的电影列表。它将使用我们在上一步中创建的动态索引以及自动完成功能。这使我们能够在前端应用程序的搜索栏中提供电影倾斜度的自动完成和模糊搜索。
在 Atlas UI 左侧栏的Build中,单击Functions 。函数提供了一种在集成来自连接的集群的数据的应用服务上执行服务器端逻辑的方法。使用聚合框架,即使没有驱动程序,您也可以创建非常强大的聚合。
单击“创建新函数”按钮并输入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 UI 左侧栏的Build中,单击GraphQL 。单击自定义解析器选项卡,然后单击添加自定义解析器按钮。对于GraphQL 字段名称,输入autocompleteTitle
,对于父类型,选择Query ,对于函数名称,选择新创建的函数autocompleteTitle
。
输入类型定义将作为此解析器的输入发送到 GraphQL API 的数据类型。返回类型定义 API 返回的数据类型。我们将发送一个字符串作为输入,并期望电影对象列表作为输出。
Scalar Type
、 String
Existing Type (List)
, [Movie]
单击“保存草稿”按钮保存自定义解析器。
单击页面顶部的“查看草稿和部署”按钮并部署您的更改。
现在,完成第一个功能设置后,请花时间测试应用程序,在搜索栏中输入一些电影标题并查看自动完成结果。
现在,有了自动完成功能,我们就可以创建一个用于突出显示和评分的新功能。此函数将返回与搜索词相匹配的电影列表,其中包含标题、所选类型以及特定电影的制作国家/地区。此外,它将返回结果的突出显示和搜索分数。突出显示包含标题和绘图字符串中的确切子字符串,其中包含匹配的搜索词。这将使我们能够在前端 UI 中突出显示找到的搜索词。
与之前的函数类似,我们将创建一个用于亮点和评分的新函数。
在 Atlas UI 左侧栏的Build中,单击Functions 。单击“创建新函数”按钮并输入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 UI 左侧栏的Build中,单击GraphQL 。单击自定义解析器选项卡,然后单击添加自定义解析器按钮。对于GraphQL 字段名称,输入filteredMovies
,对于父类型,选择查询,对于函数名称,选择新创建的函数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 "
}
单击“保存草稿”按钮保存自定义解析器。
单击页面顶部的“查看草稿和部署”按钮并部署您的更改。
现在,通过突出显示功能设置,花时间测试应用程序,在结果列表中的搜索栏滚动中输入一些电影标题,并验证模糊匹配的搜索词在匹配时在电影标题和简短情节中突出显示。
Facets 打开了许多强大的用例来对搜索结果进行分组。以下功能演示如何运行 Atlas 搜索查询来获取按电影集合中每部电影的类型值分组的结果,包括每个组的计数。
在Atlas集群的“搜索”选项卡中,为电影集合创建一个名为facets
和以下 JSON 的新索引。
{
"mappings" : {
"dynamic" : false ,
"fields" : {
"genres" : [
{
"dynamic" : true ,
"type" : " document "
},
{
"type" : " stringFacet "
}
],
"year" : [
{
"dynamic" : true ,
"type" : " document "
},
{
"representation" : " int64 " ,
"type" : " number "
}
]
}
}
}
现在创建了索引,在Atlas UI 中单击“应用程序服务”选项卡。单击 UI 中的Application-0 。在 Atlas UI 左侧栏的Build中,单击Functions 。单击“创建新函数”按钮并输入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 UI 左侧栏的Build中,单击GraphQL 。单击自定义解析器选项卡,然后单击添加自定义解析器按钮。对于GraphQL 字段名称,输入facetsGenres
,对于父类型,选择查询,对于函数名称,选择新创建的函数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 "
}
}
}
}
}
}
}
}
}
}
}
单击“保存草稿”按钮保存自定义解析器。
单击页面顶部的“查看草稿和部署”按钮并部署您的更改。
现在,通过构面设置测试应用程序并打开Genres的下拉列表。请注意,现在每个类型旁边都有一个数字,代表该类型的电影总数。
MongoDB 应用服务托管允许您托管、管理和提供应用程序的静态媒体和文档文件。您可以使用托管来存储各个内容或上传并提供整个客户端应用程序。
我们的前端应用程序包含对应用程序服务上的 GraphQL API 的所有必要调用。我们可以将整个前端应用程序导出为静态站点并将其托管在 MongoDB App Services 上。
为此,您需要在项目的根文件夹中执行以下代码。确保您已安装依赖项。
npm install
然后使用 nextjs 通过 npm 脚本构建并导出站点。
npm run build && npm run export
这将在项目的根文件夹中创建一个out
的文件夹。
在 MongoDB Atlas UI 的“应用程序服务”选项卡上。在 Atlas UI 左侧栏的管理中,单击托管。单击启用托管按钮。将文件夹的内容out
到“托管”选项卡中以上传所有文件。
单击页面顶部的“查看草稿和部署”按钮并部署您的更改。
现在单击“设置”选项卡,复制应用程序服务域并将其粘贴到您选择的浏览器中,然后按 Enter 键查看该站点。 ?