Docs 菜单
Docs 主页
/
MongoDB Atlas
/ / /

如何分页显示查询结果

在此页面上

  • 使用静态映射创建 Atlas Search 索引
  • 所需角色
  • 步骤
  • 运行查询并对结果进行分页
  • 步骤
  • 检索第 1 页并生成分页令牌
  • Retrieve Page 2 Using searchAfter
  • 使用以下内容返回到 1 页面 searchBefore
  • 使用 searchAfter$skip 从第 2 页跳转到第 5 页
  • 在分页结果中使用分面

本教程演示了如何分页显示 Atlas Search 查询的结果,以便在应用程序中构建“下一页”和“上一页”等功能。它还演示了如何使用 $skip$limit 跨页面跳转。本教程将指导您完成以下步骤:

  1. sample_mflix.movies 集合设置具有静态映射的 Atlas Search 索引。

  2. 针对已索引字段运行 Atlas Search 查询以返回连续结果,从而允许您执行以下操作:

    • 遍历页面,构建“下一页”和“上一页”的功能。

    • 从第二页跳到第五页,并在结果中跳过多页。

    • 检索结果中每个类型的电影总数。

在开始之前,请确保您的 Atlas 集群满足先决条件中所述的要求。

注意

要使用 Atlas Search $search searchSequenceToken 检索连续结果,您的 Atlas 集群必须运行 MongoDB v6.0.13+ 或 v7.0.5+。

在本部分中,您将创建一个 Atlas Search 索引,该索引使用静态映射sample_mflix.movies集合的字段编制索引。

要创建 Atlas Search 索引,您必须拥有 Project Data Access Admin 或更高的项目访问权限。

1
  1. 如果尚未显示,请从导航栏上的 Organizations 菜单中选择包含所需项目的组织。

  2. 如果尚未显示,请从导航栏的Projects菜单中选择所需的项目。

  3. 如果尚未出现,请单击侧边栏中的 Clusters(集群)。

    会显示集群页面。

2

您可以从侧边栏、 Data Explorer 或集群详细信息页面转到 Atlas Search 页面。

  1. 在侧边栏中,单击 Services 标题下的 Atlas Search

  2. Select data source 下拉菜单中选择您的集群并单击 Go to Atlas Search

    将显示 Atlas Search 页面。

  1. 单击集群的对应 Browse Collections 按钮。

  2. 展开数据库并选择集合。

  3. 单击该集合的 Search Indexes 标签页。

    将显示 Atlas Search 页面。

  1. 单击集群的名称。

  2. 单击 Atlas Search 标签页。

    将显示 Atlas Search 页面。

3
4
  • 要获得引导式体验,请选择 Atlas Search Visual Editor

  • 要编辑原始索引定义,请选择 Atlas SearchJSON Editor

5
  1. Index Name 字段中输入 pagination-tutorial

  2. Database and Collection(数据库和集合)部分中找到 sample_mflix 数据库,然后选择 movies 集合。

6

以下索引定义为以下字段配置索引:

  • title 字段作为字符串类型,以便对该字段进行全文检索

  • genres field 作为 stringFacet 类型,用于对字段进行分面搜索

  • released 字段作为日期类型,用于使用该字段对结果进行排序

您可以使用 Atlas 用户界面中的 Atlas Search Visual Editor 或 Atlas Search JSON Editor 来创建索引。

  1. 单击 Next(连接)。

  2. 单击 Refine Your Index(连接)。

  3. Index Configurations 部分中,切换以禁用 Dynamic Mapping

  4. Field Mappings 部分单击 Add Field,然后在 Add Field Mapping 窗口 Customized Configuration 标签页中逐一配置以下字段的设置后单击 Add

    字段名称
    数据类型配置

    title

    String

    genres

    stringFacet

    released

    Date

  5. 单击 Save Changes(连接)。

  1. 将默认索引定义替换为以下定义。

    1{
    2 "mappings": {
    3 "dynamic": false,
    4 "fields": {
    5 "title": {
    6 "type": "string"
    7 },
    8 "genres": {
    9 "type": "stringFacet"
    10 },
    11 "released": {
    12 "type": "date"
    13 }
    14 }
    15 }
    16}
  2. 单击 Next(连接)。

7

此时将显示一个模态窗口,让您知道索引正在构建中。

8

构建索引大约需要一分钟时间。在构建时,Status 列显示 Initial Sync。构建完成后,Status 列显示 Active

在本部分,您将运行查询,检索标题中包含术语 summer 的电影的结果。在查询中,您可以检索一个参考点,然后在后续查询中使用该参考点检索指定参考点之前和之后同一术语的其他结果。

注意

默认情况下,Atlas Search 根据文档的相关性分数对结果中的文档进行排序。如果结果中的多个文档具有相同的分数,则 Atlas Search 将返回任意排序的结果。要按确定的顺序返回文档,查询会指定一个唯一字段 released,以对结果进行排序。

本节演示了如何执行以下操作:

  1. 检索第 1 页并生成分页令牌

  2. Retrieve Page 2 Using searchAfter

  3. 使用以下内容返回到 1 页面 searchBefore

  4. 使用 searchAfter$skip 从第 2 页跳转到第 5 页

  5. 在分页结果中使用分面

要运行这些查询,您必须首先执行以下操作:

1

在终端窗口中打开 mongosh 并连接到您的集群。有关连接的详细说明,请参阅通过 mongosh 连接

2
use sample_mflix
switched to db sample_mflix
3

示例查询使用以下管道阶段来检索第一页的结果,并检索后续查询的词元或参考点:

  • 使用文本操作符搜索在 title 字段中包含 summer 的标题。

  • 使用排序选项,按 released 字段值的升序对结果进行排序。

将结果限制为 10 个文档。

在结果中仅包括文档的 titlereleasedgenres 字段。该查询还会将以下字段添加到结果中的每个文档:

  • paginationToken,这是可在后续查询中用作参考点的词元

  • score,这是文档在结果中的相关性得分

db.movies.aggregate([
{
"$search": {
"index": "pagination-tutorial",
"text": {
"path": "title",
"query": "summer"
},
"sort": { "released": 1 }
}
},
{
"$limit": 10
},
{
"$project": {
"_id": 0,
"title": 1,
"released": 1,
"genres": 1,
"paginationToken" : { "$meta" : "searchSequenceToken" },
"score": { "$meta": "searchScore" }
}
}
])
[
{
genres: [ 'Drama' ],
title: "A Summer at Grandpa's",
paginationToken: 'CKUdGgJgAA==',
score: 2.262615203857422
},
{
genres: [ 'Musical', 'Romance' ],
title: 'Summer Stock',
released: ISODate('1951-01-22T00:00:00.000Z'),
paginationToken: 'CJsFGgkpAHw/0HT///8=',
score: 3.000213623046875
},
{
genres: [ 'Comedy', 'Romance' ],
title: 'Smiles of a Summer Night',
released: ISODate('1957-12-23T00:00:00.000Z'),
paginationToken: 'CKIHGgkpAKDlpaf///8=',
score: 2.0149309635162354
},
{
genres: [ 'Drama' ],
title: 'Violent Summer',
released: ISODate('1959-11-13T00:00:00.000Z'),
paginationToken: 'CI8JGgkpAJhJh7X///8=',
score: 3.000213623046875
},
{
genres: [ 'Drama', 'Romance' ],
title: 'A Summer Place',
released: ISODate('1959-11-18T00:00:00.000Z'),
paginationToken: 'CLoJGgkpAGQJobX///8=',
score: 2.579726457595825
},
{
genres: [ 'Drama' ],
title: 'The End of Summer',
released: ISODate('1962-02-01T00:00:00.000Z'),
paginationToken: 'CK0KGgkpAAzP18X///8=',
score: 2.262615203857422
},
{
genres: [ 'Drama', 'Romance' ],
title: 'Summer and Smoke',
released: ISODate('1962-04-01T00:00:00.000Z'),
paginationToken: 'CMQKGgkpAECmB8f///8=',
score: 2.579726457595825
},
{
genres: [ 'Documentary', 'Sport' ],
title: 'The Endless Summer',
released: ISODate('1968-08-17T00:00:00.000Z'),
paginationToken: 'CO4MGgkpAJjH5vX///8=',
score: 2.579726457595825
},
{
genres: [ 'Comedy', 'Drama', 'Romance' ],
title: "Summer of '42",
released: ISODate('1971-04-09T00:00:00.000Z'),
paginationToken: 'CPQQGgkpAGRgUAkAAAA=',
score: 2.579726457595825
},
{
genres: [ 'Drama' ],
title: 'That Certain Summer',
released: ISODate('1972-11-01T00:00:00.000Z'),
paginationToken: 'COwRGgkpAPQV0hQAAAA=',
score: 2.579726457595825
}
]

要检索其他结果,您需要指定要检索结果的参考点。此查询演示了如何检索结果,以便在应用程序中构建类似“下一页”的功能。

示例查询使用以下管道阶段,利用 searchSequenceToken 之前查询同一术语时生成的令牌检索第二页的结果:

将结果限制为 10 个文档。

仅包括结果中文档的 titlereleasedgenres 字段。它还将以下字段添加到结果中的每个文档:

  • paginationToken,这是可在后续查询中用作参考点的令牌

  • score,这是文档在结果中的相关性得分

db.movies.aggregate([
{
"$search": {
"index": "pagination-tutorial",
"text": {
"path": "title",
"query": "summer"
},
"searchAfter": "COwRGgkpAPQV0hQAAAA=",
"sort": { "released": 1 }
}
},
{
"$limit": 10
},
{
"$project": {
"_id": 0,
"title": 1,
"released": 1,
"genres": 1,
"paginationToken" : { "$meta" : "searchSequenceToken" },
"score": { "$meta": "searchScore" }
}
}
])
[
{
genres: [ 'Drama' ],
title: 'Summer Wishes, Winter Dreams',
released: ISODate('1974-09-09T00:00:00.000Z'),
paginationToken: 'CMwSGgkpAECHcCIAAAA=',
score: 2.262615203857422
},
{
genres: [ 'Drama', 'Thriller' ],
title: 'Shadows of a Hot Summer',
released: ISODate('1978-09-01T00:00:00.000Z'),
paginationToken: 'CPEVGgkpAGw/qz8AAAA=',
score: 2.0149309635162354
},
{
genres: [ 'Drama' ],
title: 'Indian Summer',
released: ISODate('1978-11-01T00:00:00.000Z'),
paginationToken: 'CNYRGgkpAFhj5UAAAAA=',
score: 3.000213623046875
},
{
genres: [ 'Drama' ],
title: 'Indian Summer',
released: ISODate('1978-11-01T00:00:00.000Z'),
paginationToken: 'CNsRGgkpAFhj5UAAAAA=',
score: 3.000213623046875
},
{
genres: [ 'Drama', 'Mystery' ],
title: 'One Deadly Summer',
released: ISODate('1983-05-11T00:00:00.000Z'),
paginationToken: 'COwcGgkpAAjtIGIAAAA=',
score: 2.579726457595825
},
{
genres: [ 'Comedy' ],
title: 'Summer Rental',
released: ISODate('1985-08-09T00:00:00.000Z'),
paginationToken: 'CL8fGgkpABTypHIAAAA=',
score: 3.000213623046875
},
{
genres: [ 'Drama', 'Romance' ],
title: 'Summer',
released: ISODate('1986-08-29T00:00:00.000Z'),
paginationToken: 'CO0gGgkpAHCiY3oAAAA=',
score: 3.5844719409942627
},
{
genres: [ 'Drama', 'Thriller' ],
title: 'Summer Camp Nightmare',
released: ISODate('1987-04-17T00:00:00.000Z'),
paginationToken: 'CNkiGgkpAHQ/CX8AAAA=',
score: 2.579726457595825
},
{
genres: [ 'Action', 'Crime', 'Drama' ],
title: 'Cold Summer of 1953',
released: ISODate('1988-06-01T00:00:00.000Z'),
paginationToken: 'CNsjGgkpACjVTYcAAAA=',
score: 2.262615203857422
},
{
genres: [ 'Drama', 'War' ],
title: 'That Summer of White Roses',
released: ISODate('1989-07-11T00:00:00.000Z'),
paginationToken: 'CI0mGgkpALSEc48AAAA=',
score: 2.0149309635162354
}
]

要检索以前的结果,需要指定要检索结果的参考点。此查询演示了如何检索结果以在应用程序中构建类似于“上一页”的功能。

该示例查询使用了以下管道阶段,利用之前查询同一术语时由 searchSequenceToken 生成的令牌返回第一页的结果:

  • 使用文本操作符搜索在 title 字段中包含 summer 的标题。

  • 使用排序选项,按 released 字段值的升序对结果进行排序。

  • 使用与您运行到使用 检索页面 的查询结果中的第十一个文档关联的分页令牌,将Atlas Search结果中的文档 返回到1 102searchAfter

将结果限制为 10 个文档。

仅包括结果中文档的 titlereleasedgenres 字段。它还将以下字段添加到结果中的每个文档:

  • paginationToken,这是可在后续查询中用作参考点的词元

  • score,这是文档在结果中的相关性得分

注意

默认情况下,Atlas Search 会以相反的顺序返回指定标记的查询结果,以便在参考点之前检索结果。为了按顺序返回文档,查询使用了 toArray() 和 JavaScript reverse() 方法。

db.movies.aggregate([
{
"$search": {
"index": "pagination-tutorial",
"text": {
"path": "title",
"query": "summer"
},
"searchBefore": "CMwSGgkpAECHcCIAAAA=",
"sort": { "released": 1 }
}
},
{
"$limit": 10
},
{
"$project": {
"_id": 0,
"title": 1,
"released": 1,
"genres": 1,
"paginationToken" : { "$meta" : "searchSequenceToken" },
"score": { "$meta": "searchScore" }
}
}
]).toArray().reverse()
[
{
genres: [ 'Drama' ],
title: "A Summer at Grandpa's",
paginationToken: 'CKUdGgJgAA==',
score: 2.262615203857422
},
{
genres: [ 'Musical', 'Romance' ],
title: 'Summer Stock',
released: ISODate('1951-01-22T00:00:00.000Z'),
paginationToken: 'CJsFGgkpAHw/0HT///8=',
score: 3.000213623046875
},
{
genres: [ 'Comedy', 'Romance' ],
title: 'Smiles of a Summer Night',
released: ISODate('1957-12-23T00:00:00.000Z'),
paginationToken: 'CKIHGgkpAKDlpaf///8=',
score: 2.0149309635162354
},
{
genres: [ 'Drama' ],
title: 'Violent Summer',
released: ISODate('1959-11-13T00:00:00.000Z'),
paginationToken: 'CI8JGgkpAJhJh7X///8=',
score: 3.000213623046875
},
{
genres: [ 'Drama', 'Romance' ],
title: 'A Summer Place',
released: ISODate('1959-11-18T00:00:00.000Z'),
paginationToken: 'CLoJGgkpAGQJobX///8=',
score: 2.579726457595825
},
{
genres: [ 'Drama' ],
title: 'The End of Summer',
released: ISODate('1962-02-01T00:00:00.000Z'),
paginationToken: 'CK0KGgkpAAzP18X///8=',
score: 2.262615203857422
},
{
genres: [ 'Drama', 'Romance' ],
title: 'Summer and Smoke',
released: ISODate('1962-04-01T00:00:00.000Z'),
paginationToken: 'CMQKGgkpAECmB8f///8=',
score: 2.579726457595825
},
{
genres: [ 'Documentary', 'Sport' ],
title: 'The Endless Summer',
released: ISODate('1968-08-17T00:00:00.000Z'),
paginationToken: 'CO4MGgkpAJjH5vX///8=',
score: 2.579726457595825
},
{
genres: [ 'Comedy', 'Drama', 'Romance' ],
title: "Summer of '42",
released: ISODate('1971-04-09T00:00:00.000Z'),
paginationToken: 'CPQQGgkpAGRgUAkAAAA=',
score: 2.579726457595825
},
{
genres: [ 'Drama' ],
title: 'That Certain Summer',
released: ISODate('1972-11-01T00:00:00.000Z'),
paginationToken: 'COwRGgkpAPQV0hQAAAA=',
score: 2.579726457595825
}
]

要跳过结果并从第 2 页跳转到第 5 页,请使用 searchSequenceToken 生成的令牌来指定要检索结果的参考点,然后跳过结果中的二十个文档。此查询演示了如何检索结果以在应用程序中构建允许跳过页面的功能。

示例查询使用以下管道阶段跳转到第 5 页上的结果,方法是使用 searchSequenceToken从同一术语的先前查询中生成的令牌,并使用 $skip$limit 阶段:

跳过结果中指定引用点之后的20 个文档,该引用点是与您运行使用 检索页面2 searchAfter的查询的结果中的第二十个文档关联的词元。

将结果限制为 10 个文档。

仅包括结果中文档的 titlereleasedgenres 字段。它还将以下字段添加到结果中的每个文档:

  • paginationToken,这是可在后续查询中用作参考点的词元

  • score,这是文档在结果中的相关性得分

db.movies.aggregate([
{
"$search": {
"index": "pagination-tutorial",
"text": {
"path": "title",
"query": "summer"
},
"searchAfter": "COwRGgkpAPQV0hQAAAA=",
"sort": { "released": 1 }
}
},
{
"$skip": 20
},
{
"$limit": 10
},
{
"$project": {
"_id": 0,
"title": 1,
"released": 1,
"genres": 1,
"paginationToken" : { "$meta" : "searchSequenceToken" },
"score": { "$meta": "searchScore" }
}
}
])
[
{
genres: [ 'Drama' ],
title: 'A Storm in Summer',
released: ISODate('2000-02-27T00:00:00.000Z'),
paginationToken: 'CO5FGgkpAChakN0AAAA=',
score: 2.262615203857422
},
{
genres: [ 'Comedy', 'Romance' ],
title: 'Wet Hot American Summer',
released: ISODate('2002-04-11T00:00:00.000Z'),
paginationToken: 'CKtIGgkpAFBUIu0AAAA=',
score: 2.262615203857422
},
{
genres: [ 'Comedy', 'Drama', 'Romance' ],
title: 'Summer Things',
released: ISODate('2002-10-09T00:00:00.000Z'),
paginationToken: 'CIpPGgkpAFxzxvAAAAA=',
score: 3.000213623046875
},
{
genres: [ 'Adventure', 'Drama', 'Family' ],
title: 'Wolf Summer',
released: ISODate('2003-02-28T00:00:00.000Z'),
paginationToken: 'COZWGgkpAGS6ofMAAAA=',
score: 3.000213623046875
},
{
genres: [ 'Animation', 'Adventure' ],
title: 'Nasu: Summer in Andalusia',
released: ISODate('2003-06-26T00:00:00.000Z'),
paginationToken: 'CNlaGgkpAMxoAfYAAAA=',
score: 2.262615203857422
},
{
genres: [ 'Drama' ],
title: 'Spring, Summer, Fall, Winter... and Spring',
released: ISODate('2004-05-28T00:00:00.000Z'),
paginationToken: 'CJ5ZGgkpAOjnyPwAAAA=',
score: 1.8161234855651855
},
{
genres: [ 'Comedy', 'Drama', 'Romance' ],
title: 'Summer Storm',
released: ISODate('2004-09-02T00:00:00.000Z'),
paginationToken: 'CMVfGgkpAMRwvP4AAAA=',
score: 3.000213623046875
},
{
genres: [ 'Drama' ],
title: 'Summer in the Golden Valley',
released: ISODate('2004-10-08T00:00:00.000Z'),
paginationToken: 'CNNWGgkpALTVdf8AAAA=',
score: 2.0149309635162354
},
{
genres: [ 'Drama', 'Romance' ],
title: 'My Summer of Love',
released: ISODate('2005-07-01T00:00:00.000Z'),
paginationToken: 'CL5aGgkpAEyxzwQBAAA=',
score: 2.262615203857422
},
{
genres: [ 'Drama' ],
title: 'Summer in Berlin',
released: ISODate('2006-01-05T00:00:00.000Z'),
paginationToken: 'CPZmGgkpANzclwgBAAA=',
score: 2.579726457595825
}
]

本节演示了如何将 searchSequenceToken 用于 Atlas Search 分面。

示例查询使用以下管道阶段:

  • 使用 分面收集器搜索在 title 字段中包含 summer 的标题。

  • 使用 facets 选项,检索每种类型结果中的电影总数。

添加 paginationToken 字段,用于在使用 searchSequenceToken 选项生成的结果中存储每个文档的词元。

将结果限制为 10 个文档。

返回以下字段:

  • docs 字段,其中仅包含结果中文档的 titlereleasedgenres 字段以及 paginationToken 字段。

  • meta 字段,其中包含存储在 $$SEARCH_META 变量中的每种类型结果中的电影总数。

db.movies.aggregate([
{
"$search": {
"index": "pagination-tutorial",
"facet": {
"operator": {
"text": {
"path": "title",
"query": "summer"
}
},
"facets": {
"genresFacet": {
"type": "string",
"path": "genres"
}
}
}
}
},
{
"$addFields": {
"paginationToken" : { "$meta" : "searchSequenceToken" }
}
},
{ "$limit": 10 },
{
"$facet": {
"docs": [
{ "$project":
{
"_id": 0,
"title": 1,
"released": 1,
"genres": 1,
"paginationToken" : 1
}
}
],
"meta": [
{ "$replaceWith": "$$SEARCH_META" },
{ "$limit": 1 }
]
}
},
{
"$set": {
"meta": {
"$arrayElemAt": ["$meta", 0]
}
}
}
])
[
{
docs: [
{
genres: [ 'Drama', 'Romance' ],
title: 'Summer',
released: ISODate('1986-08-29T00:00:00.000Z'),
paginationToken: 'CO0gFf1nZUA='
},
{
genres: [ 'Musical', 'Romance' ],
title: 'Summer Stock',
released: ISODate('1951-01-22T00:00:00.000Z'),
paginationToken: 'CJsFFYADQEA='
},
{
genres: [ 'Drama' ],
title: 'Violent Summer',
released: ISODate('1959-11-13T00:00:00.000Z'),
paginationToken: 'CI8JFYADQEA='
},
{
genres: [ 'Drama' ],
title: 'Indian Summer',
released: ISODate('1978-11-01T00:00:00.000Z'),
paginationToken: 'CNYRFYADQEA='
},
{
genres: [ 'Drama' ],
title: 'Indian Summer',
released: ISODate('1978-11-01T00:00:00.000Z'),
paginationToken: 'CNsRFYADQEA='
},
{
genres: [ 'Comedy' ],
title: 'Summer Rental',
released: ISODate('1985-08-09T00:00:00.000Z'),
paginationToken: 'CL8fFYADQEA='
},
{
genres: [ 'Comedy', 'Drama', 'Romance' ],
title: 'Summer Things',
released: ISODate('2002-10-09T00:00:00.000Z'),
paginationToken: 'CIpPFYADQEA='
},
{
genres: [ 'Adventure', 'Drama', 'Family' ],
title: 'Wolf Summer',
released: ISODate('2003-02-28T00:00:00.000Z'),
paginationToken: 'COZWFYADQEA='
},
{
genres: [ 'Comedy', 'Drama', 'Romance' ],
title: 'Summer Storm',
released: ISODate('2004-09-02T00:00:00.000Z'),
paginationToken: 'CMVfFYADQEA='
},
{
genres: [ 'Drama', 'Romance' ],
title: 'Summer Palace',
released: ISODate('2007-04-18T00:00:00.000Z'),
paginationToken: 'CIRrFYADQEA='
}
],
meta: {
count: { lowerBound: Long('65') },
facet: {
genresFacet: {
buckets: [
{ _id: 'Drama', count: Long('48') },
{ _id: 'Romance', count: Long('20') },
{ _id: 'Comedy', count: Long('19') },
{ _id: 'Family', count: Long('7') },
{ _id: 'Adventure', count: Long('5') },
{ _id: 'Crime', count: Long('5') },
{ _id: 'Mystery', count: Long('5') },
{ _id: 'Thriller', count: Long('5') },
{ _id: 'Horror', count: Long('4') },
{ _id: 'Action', count: Long('3') }
]
}
}
}
}
]

后退

对结果进行分页