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

facet

在此页面上

  • 定义
  • 限制
  • 语法
  • 字段
  • 分面定义
  • 字符串分面
  • 数值分面
  • 日期分面
  • 分面结果
  • SEARCH_META 聚合变量
  • 限制
  • 示例
facet

facet 收集器按指定分面字段中的值或范围对结果进行分组,并返回每个组的计数。

您可以将facet 与 和$search $searchMeta阶段一起使用。MongoDB建议使用facet $searchMeta和 阶段来检索仅针对该查询的元数据结果。要使用 阶段检索元数据结果和查询结果,必须使用$search $$SEARCH_META聚合变量。请参阅SEARCH_META 聚合变量以学习;了解详情。

您不能使用 explain 运行 facet 查询。

facet 通过以下语法实现:

{
"$searchMeta"|"$search": {
"index": <index name>, // optional, defaults to "default"
"facet": {
"operator": {
<operator-specifications>
},
"facets": {
<facet-definitions>
}
}
}
}
字段
类型
必需?
说明

facets

文档

用于对每个分面(Facet)的数据进行分桶的信息。您必须指定至少一个分面定义。

operator

文档

no

用于执行分面操作的操作符。如省略,Atlas Search 将对集合中的所有文档执行分面操作。

分面定义文档包含分面名称和特定于分面类型的选项。Atlas Search 支持以下类型的分面:

字符串分面允许您根据指定字符串字段中最常见的字符串值缩小Atlas Search结果的范围。请注意,字符串字段的索引必须为 stringFacet 。要对嵌入式文档中的字符串字段分面(Facet),您还必须将父字段作为文档类型索引。当您对数组或嵌入式文档中的字符串进行分面(Facet)面时, Atlas Search会根据匹配的根文档的数量返回分面(Facet)计数。

字符串分面采用以下语法:

{
"$searchMeta": {
"facet":{
"operator": {
<operator-specification>
},
"facets": {
"<facet-name>" : {
"type" : "string",
"path" : "<field-path>",
"numBuckets" : <number-of-categories>,
}
}
}
}
}
选项
类型
说明
必需?

numBuckets

int

结果中要返回的最大分面类别数量。值必须小于或等于 1000。如果指定,如果数据分组的类别数量少于请求的数量,Atlas Search 返回的类别数量可能会少于请求的数量。如果省略,则默认为 10 ,这意味着 Atlas Search 将仅返回按计数排列靠前的 10分面类别。

no

path

字符串

用于分面的字段路径。您可以指定一个已建立 stringFacet 索引的字段。

type

字符串

分面类型。值必须是 string

例子

以下示例将对 sample_mflix.movies 集合使用名为 default 的索引。集合中的 genres 字段被索引为 stringFacet 类型,而 year 字段被索引为 number 类型。

{
"mappings": {
"dynamic": false,
"fields": {
"genres": {
"type": "stringFacet"
},
"year": {
"type": "number"
}
}
}
}

该查询使用 $searchMeta 阶段在 movies 集合中的 year 字段内搜索从 2000 年到 2015 年的电影,并检索每种类型的电影数量。

1db.movies.aggregate([
2 {
3 "$searchMeta": {
4 "facet": {
5 "operator": {
6 "range": {
7 "path": "year",
8 "gte": 2000,
9 "lte": 2015
10 }
11 },
12 "facets": {
13 "genresFacet": {
14 "type": "string",
15 "path": "genres"
16 }
17 }
18 }
19 }
20 }
21])
1[
2 {
3 count: { lowerBound: Long('12568') },
4 facet: {
5 genresFacet: {
6 buckets: [
7 { _id: 'Drama', count: Long('7079') },
8 { _id: 'Comedy', count: Long('3689') },
9 { _id: 'Romance', count: Long('1764') },
10 { _id: 'Thriller', count: Long('1584') },
11 { _id: 'Documentary', count: Long('1472') },
12 { _id: 'Action', count: Long('1471') },
13 { _id: 'Crime', count: Long('1367') },
14 { _id: 'Adventure', count: Long('1056') },
15 { _id: 'Horror', count: Long('866') },
16 { _id: 'Biography', count: Long('796') }
17 ]
18 }
19 }
20 }
21]

要了解有关这些结果的更多信息,请参阅分面结果

重要

numberFacet 现已弃用。请改用数字。

数字分面允许您将搜索结果分解为不同的数字范围,从而确定数字值在搜索结果中的频率。当您对数组或嵌入式文档中的数字进行分面(Facet)时, Atlas Search会根据匹配的根文档的数量返回分面(Facet)计数。

数字分面采用以下语法:

{
"$searchMeta": {
"facet":{
"operator": {
<operator-specification>
},
"facets": {
"<facet-name>" : {
"type" : "number",
"path" : "<field-path>",
"boundaries" : <array-of-numbers>,
"default": "<bucket-name>"
}
}
}
}
}
选项
类型
说明
必需?

boundaries

数字数组

按升序排列的数值列表,用于指定每个存储桶的边界。您必须指定至少两个边界,且边界值小于或等于 1000 ([2, 1000] )。每对相邻的值都充当存储桶的包含下限和不包含上限。您可以指定以下BSON 类型值的任意组合:

  • 32 位整数 (int32)

  • 64 位整数 (int64)

  • 64 位二进制浮点数 (double)

default

字符串

附加存储桶的名称,它可用于对从操作符返回的不属于指定边界的文档进行计数。如果省略,Atlas Search 还会包含不属于指定存储桶的分面运算符的结果,但不将其包含在任何存储桶计数中。

no

path

字符串

用于分面(Facet)面的字段路径。您可以指定一个被索引为数字类型的字段。

type

字符串

分面类型。值必须是 number

例子

以下示例使用default sample_mflix.movies集合上名为 的索引。集合中的year 字段被索引为数字类型。

{
"mappings": {
"dynamic": false,
"fields": {
"year": [
{
"type": "number"
}
]
}
}
}

此查询使用 $searchMeta 阶段在 movies 集合中的 year 字段中搜索 19802000 年间的影片,并检索查询的元数据结果。此查询指定了三个存储桶:

  • 1980,包括此存储桶的下限

  • 19901980 存储桶的不含上限以及此存储桶的包含下限

  • 20001990存储桶的独占上限

该查询还会指定一个名为 otherdefault 存储桶,以便检索不属于任何指定边界的查询结果。

1db.movies.aggregate([
2 {
3 "$searchMeta": {
4 "facet": {
5 "operator": {
6 "range": {
7 "path": "year",
8 "gte": 1980,
9 "lte": 2000
10 }
11 },
12 "facets": {
13 "yearFacet": {
14 "type": "number",
15 "path": "year",
16 "boundaries": [1980,1990,2000],
17 "default": "other"
18 }
19 }
20 }
21 }
22 }
23])
1[
2 {
3 count: { lowerBound: Long('6095') },
4 facet: {
5 yearFacet: {
6 buckets: [
7 { _id: 1980, count: Long('1956') },
8 { _id: 1990, count: Long('3558') },
9 { _id: 'other', count: Long('581') }
10 ]
11 }
12 }
13 }
14]

要了解有关这些结果的更多信息,请参阅分面结果

重要

dateFacet 现已弃用。请改用日期。

日期分面允许您根据日期缩小搜索结果的范围。当您对数组或嵌入式文档中的日期分面(Facet)时, Atlas Search会根据匹配的根文档的数量返回分面(Facet)计数。

日期分面采用以下语法:

{
"$searchMeta": {
"facet":{
"operator": {
<operator-specification>
},
"facets": {
"<facet-name>" : {
"type" : "date",
"path" : "<field-path>",
"boundaries" : <array-of-dates>,
"default": "<bucket-name>"
}
}
}
}
}
选项
类型
说明
必需?

boundaries

数字数组

指定每个存储桶边界的日期值列表。您必须指定:

  • 至少两个边界,且小于或等于 1,000 ([2, 1000])

  • 值按升序排列,最早日期在最前面

每对相邻的值都充当存储桶的包含下限和不包含上限。

default

字符串

附加存储桶的名称,它可用于对从操作符返回的不属于指定边界的文档进行计数。如果省略,Atlas Search 也会包含不属于指定存储桶的分面运算符的结果,但 Atlas Search 不会将这些结果包含在任何存储桶计数中。

no

path

字符串

用于分面(Facet)面的字段路径。您可以指定一个被索引为日期类型的字段。

type

字符串

分面类型。值必须是 date

例子

以下示例使用default sample_mflix.movies集合上名为 的索引。集合中的released 字段被索引为日期类型。

{
"mappings": {
"dynamic": false,
"fields": {
"released": [
{
"type": "date"
}
]
}
}
}

此查询使用 $searchMeta 阶段在 movies 集合中的 released 字段中搜索 20002015 年间的影片,并检索查询字符串的元数据结果。此查询指定了四个存储桶:

  • 2000-01-01,包括此存储桶的下限

  • 2005-01-012000-01-01 存储桶的不含上限以及此存储桶的包含下限

  • 2010-01-012005-01-01 存储桶的不含上限以及此存储桶的包含下限

  • 2015-01-012010-01-01存储桶的独占上限

该查询还会指定一个名为 otherdefault 存储桶,以便检索不属于任何指定边界的查询结果。

1db.movies.aggregate([
2 {
3 "$searchMeta": {
4 "facet": {
5 "operator": {
6 "range": {
7 "path": "released",
8 "gte": ISODate("2000-01-01T00:00:00.000Z"),
9 "lte": ISODate("2015-01-31T00:00:00.000Z")
10 }
11 },
12 "facets": {
13 "yearFacet": {
14 "type": "date",
15 "path": "released",
16 "boundaries": [ISODate("2000-01-01"), ISODate("2005-01-01"), ISODate("2010-01-01"), ISODate("2015-01-01")],
17 "default": "other"
18 }
19 }
20 }
21 }
22 }
23])
1[
2 {
3 count: { lowerBound: Long('11922') },
4 facet: {
5 yearFacet: {
6 buckets: [
7 {
8 _id: ISODate('2000-01-01T00:00:00.000Z'),
9 count: Long('3028')
10 },
11 {
12 _id: ISODate('2005-01-01T00:00:00.000Z'),
13 count: Long('3953')
14 },
15 {
16 _id: ISODate('2010-01-01T00:00:00.000Z'),
17 count: Long('4832')
18 },
19 { _id: 'other', count: Long('109') }
20 ]
21 }
22 }
23 }
24]

要了解有关这些结果的更多信息,请参阅分面结果

对于分面查询,Atlas Search 返回定义的分面名称与结果中该分面的存储桶数组的映射。分面结果文档包含 buckets 选项,此选项是分面结果存储桶的数组。数组中的每个分面存储桶文档都包含以下字段:

选项
类型
说明

_id

对象

标识此方面存储桶的唯一标识符。此值与正在分面的数据类型相匹配。

count

int

此分面存储桶中的文档计数。要了解有关 count 字段的详情,请参阅计算 Atlas Search 结果

当您使用 $search 阶段运行查询时,Atlas Search 会将元数据结果存储在 $$SEARCH_META 变量中,并且仅返回搜索结果。您可以在所有支持的聚合管道阶段使用 $$SEARCH_META 变量来查看 $search 查询的元数据结果。

只有同时需要搜索结果和元数据结果时,MongoDB 才建议使用 $$SEARCH_META 变量。否则,请使用:

适用以下限制:

  • 只能对单个字段运行分面查询。无法对字段群组运行分面查询。

  • 只能在运行 MongoDB v6.0 的集群上对分片集合运行分面查询。

以下示例使用 sample_mflix.movies 集合。元数据结果示例演示如何使用 facet 运行 $searchMeta 查询,以便仅检索结果中的元数据。元数据和搜索结果示例演示了如何使用 facet$SEARCH_META 聚合变量运行 $search 查询,以便检索搜索结果和元数据结果。

索引定义为要索引的字段指定了以下内容:

字段名称
数据类型

directors

year

released

{
"mappings": {
"dynamic": false,
"fields": {
"directors": {
"type": "stringFacet"
},
"year": {
"type": "number"
},
"released": {
"type": "date"
}
}
}
}

以下查询搜索 2000 年 1 月 1 日至 2015 年 1 月 31 日之间上映的电影。它请求 directorsyear 字段的元数据。

1db.movies.aggregate([
2 {
3 "$searchMeta": {
4 "facet": {
5 "operator": {
6 "range": {
7 "path": "released",
8 "gte": ISODate("2000-01-01T00:00:00.000Z"),
9 "lte": ISODate("2015-01-31T00:00:00.000Z")
10 }
11 },
12 "facets": {
13 "directorsFacet": {
14 "type": "string",
15 "path": "directors",
16 "numBuckets" : 7
17 },
18 "yearFacet" : {
19 "type" : "number",
20 "path" : "year",
21 "boundaries" : [2000,2005,2010, 2015]
22 }
23 }
24 }
25 }
26 }
27])
1[
2 {
3 count: { lowerBound: Long('11922') },
4 facet: {
5 yearFacet: {
6 buckets: [
7 { _id: 2000, count: Long('3064') },
8 { _id: 2005, count: Long('4035') },
9 { _id: 2010, count: Long('4553') }
10 ]
11 },
12 directorsFacet: {
13 buckets: [
14 { _id: 'Takashi Miike', count: Long('26') },
15 { _id: 'Johnnie To', count: Long('20') },
16 { _id: 'Steven Soderbergh', count: Long('18') },
17 { _id: 'Michael Winterbottom', count: Long('16') },
18 { _id: 'Ridley Scott', count: Long('15') },
19 { _id: 'Tyler Perry', count: Long('15') },
20 { _id: 'Clint Eastwood', count: Long('14') }
21 ]
22 }
23 }
24 }
25]

结果显示 sample_mflix.movies 集合中的以下计数:

  • Atlas Search 为查询返回的从 2000 年(含下限)到 2015 年(不含上限)的电影数量

  • Atlas Search 为查询返回的每位导演的电影数量

索引定义为要索引的字段指定了以下内容:

字段名称
数据类型

genres

released

{
"mappings": {
"dynamic": false,
"fields": {
"genres": {
"type": "stringFacet"
},
"released": {
"type": "date"
}
}
}
}

以下查询使用 $search 阶段搜索 1999 年 7 月 01 上映的电影。该查询包括 $facet 阶段,用于使用以下子管道阶段处理输入文档:

  • $project 阶段,在 docs 输出字段中排除文件中除titlereleased 字段以外的所有字段

  • $limit 阶段来执行以下操作:

    • $search 阶段的输出限制为 2 个文档

    • meta 输出字段中将输出限制为 1 个文档。

    注意

    限制必须很小,结果才能适合 16 MB 的文档。

  • $replaceWith 阶段将存储在 $$SEARCH_META 变量中的元数据结果包含在 meta 输出字段中

该查询还包括用于添加 meta 字段的 $set 阶段。

注意

要查看以下查询的元数据结果,Atlas Search 必须返回与该查询匹配的文档。

1db.movies.aggregate([
2 {
3 "$search": {
4 "facet": {
5 "operator": {
6 "near": {
7 "path": "released",
8 "origin": ISODate("1999-07-01T00:00:00.000+00:00"),
9 "pivot": 7776000000
10 }
11 },
12 "facets": {
13 "genresFacet": {
14 "type": "string",
15 "path": "genres"
16 }
17 }
18 }
19 }
20 },
21 { "$limit": 2 },
22 {
23 "$facet": {
24 "docs": [
25 { "$project":
26 {
27 "title": 1,
28 "released": 1
29 }
30 }
31 ],
32 "meta": [
33 {"$replaceWith": "$$SEARCH_META"},
34 {"$limit": 1}
35 ]
36 }
37 },
38 {
39 "$set": {
40 "meta": {
41 "$arrayElemAt": ["$meta", 0]
42 }
43 }
44 }
45])
1[
2 {
3 docs: [
4 {
5 _id: ObjectId('573a1393f29313caabcde1ae'),
6 title: 'Begone Dull Care',
7 released: ISODate('1999-07-01T00:00:00.000Z')
8 },
9 {
10 _id: ObjectId('573a13a9f29313caabd2048a'),
11 title: 'Fara',
12 released: ISODate('1999-07-01T00:00:00.000Z')
13 }
14 ],
15 meta: {
16 count: { lowerBound: Long('20878') },
17 facet: {
18 genresFacet: {
19 buckets: [
20 { _id: 'Drama', count: Long('12149') },
21 { _id: 'Comedy', count: Long('6436') },
22 { _id: 'Romance', count: Long('3274') },
23 { _id: 'Crime', count: Long('2429') },
24 { _id: 'Thriller', count: Long('2400') },
25 { _id: 'Action', count: Long('2349') },
26 { _id: 'Adventure', count: Long('1876') },
27 { _id: 'Documentary', count: Long('1755') },
28 { _id: 'Horror', count: Long('1432') },
29 { _id: 'Biography', count: Long('1244') }
30 ]
31 }
32 }
33 }
34 }
35]

要了解有关这些结果的更多信息,请参阅分面结果

后退

存在