Make the MongoDB docs better! We value your opinion. Share your feedback for a chance to win $100.
Click here >
Docs 菜单
Docs 主页
/ /

facet (MongoDB搜索操作符)

facet

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

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

如果在 embeddedDocuments 字段类型定义中定义了 storedSource ,就可以使用 returnScope returnStoredSource 对对象数组内的嵌套字段进行分面。否则,您只能在根 embeddedDocuments 类型字段上进行分面。关于分面的示例:

  • 嵌套在对象数组内的字段,请参阅 returnScope 示例。

  • embeddedDocuments 类型字段,请参阅 分面查询。

facet 通过以下语法实现:

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

facets

文档

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

operator

文档

no

用于执行分面(Facet)面操作的操作符。如果省略, MongoDB搜索将对集合中的所有文档执行分面(Facet)。

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

重要

stringFacet 现已过时。请改用令牌,以改进分面(Facet)。

要详细了解分面(Facet)的更新和过时字段类型之间的区别,请参阅比较分面(Facet)的字段类型。

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

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

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

numBuckets

int

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

no

path

字符串

用于分面的字段路径。您可将被索引字段指定为 token

type

字符串

分面类型。值必须是 string

例子

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

{
"mappings": {
"dynamic": false,
"fields": {
"genres": {
"type": "token"
},
"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)。

要详细了解分面(Facet)的更新和过时字段类型之间的区别,请参阅比较分面(Facet)的字段类型。

数字分面允许您将搜索结果分解为不同的数字范围,从而确定数字值在搜索结果中的频率。当您对数组或嵌入式文档中的数字进行分面(Facet)时, MongoDB 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

字符串

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

no

path

字符串

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

type

字符串

分面类型。值必须是 number

例子

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

{
"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)。

要详细了解分面(Facet)的更新和过时字段类型之间的区别,请参阅比较分面(Facet)的字段类型。

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

日期分面采用以下语法:

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

boundaries

数字数组

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

  • 至少两个边界,而它们应小于或等于 1000 ([2, 1000])

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

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

default

字符串

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

no

path

字符串

用于分面的字段路径。您可将被索引字段指定为 date 类型。

type

字符串

分面类型。值必须是 date

例子

以下示例将对 sample_mflix.movies 集合使用名为 default 的索引。集合中的 released 字段将索引为 date 类型。

{
"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]

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

与过时的类型(stringFacetnumberFacetdateFacet)相比,更新的MongoDB搜索字段类型改进了支持分面(Facet)的功能。下表概述了功能上的主要区别:

分面(Facet)类别
更新的字段类型
过时的分面(Facet)类型
主要差异

字符串

stringFacet(已过时)

规范器支持token 类型支持转换分面(Facet)桶的规范器。示例,对于 normalizer: lowercase,“ADIDAS”和“adidas”计入同一存储桶,而 stringFacet 将它们视为单独的存储桶。

数值

numberFacet(已过时)

数组支持number 类型考虑分面(Facet)存储桶数组中的值。示例,具有数组值 [0, 10] 的文档同时计入存储桶 [1, 5][6, 10],而 numberFacet 完全忽略数组值。

Date

dateFacet(已过时)

数组支持date 类型考虑分面(Facet)存储桶数组中的值。示例,包含日期的数组值可以影响多个日期范围存储桶,而 dateFacet 会完全忽略数组值。

注意

当为同一字段定义过时和更新的字段类型时,过时的分面(Facet)类型优先。示例,如果为字段同时定义了 tokenstringFacet,分面(Facet)计算将使用 stringFacet 映射。

对于分面(Facet)查询, MongoDB Search 返回定义的分面(Facet)名称到结果中该分面(Facet)的存储桶大量的映射。分面(Facet)结果文档包含 buckets 选项,它是分面(Facet)结果存储桶的大量。大量中的每个分面(Facet)存储桶文档都包含以下字段:

选项
类型
说明

_id

对象

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

count

int

此分面(Facet)存储桶中的文档计数。要学习;了解有关 count字段的更多信息,请参阅对MongoDB搜索结果进行计数。

MongoDB Search 允许您同时查看和选择同一分面(Facet)中的多个存储桶。通常,选择分面(Facet)中的存储桶会根据该选择筛选搜索结果,并更改所有分面的计数。

例子

假设 sample_airbnb.listings集合的索引定义指定了以下字段的分面:

  • cancellation_policy

  • room_type

  • accommodates

cancellation_policy分面(Facet)具有以下存储桶:

  • flexible

  • moderate

  • strict_14_with_grace_period

  • super_strict_30

  • super_strict_60

每个都有自己的结果计数。当您搜索moderate cancellation_policy 时,其他四个存储桶的计数将变为 0。此外,room_typeaccommodates 分面(Facet)中的存储桶计数减少为每个存储桶中也具有 flexible cancellation_policy 的结果数。

如果您需要更精细地控制分面如何影响搜索结果计数,请在分面查询中启用doesNotAffect属性启用多选分面。这些分面仍会过滤结果,但查询不会更改其结果计数。

例子

考虑对 sample_airbnb.listings 集合的查询,查找包含 moderate cancellation_policy 的文档。如果您指定 doesNotAffect 值为 cancellation_policy,则 cancellation_policy 分面中存储桶的计数不会改变,但其他分面的存储桶结果计数将减少为每个存储桶中也具有 moderate cancellation_policy 的结果数量。

有关更多信息,请参阅多选分面(Facet)示例。

最后,对于具有多个分面的使用案例,限制哪些其他过滤器影响给定分面可能很有用。您可以通过在任何过滤器的 doesNotAffect 属性中指定任何分面(包括其他字段上的分面)来实现此目的。这使您能够一眼看出哪些选择会更快或更慢地缩小选项范围。

例子

考虑对 sample_airbnb.listings集合查询accommodates 值为 3 的文档。如果您指定的 doesNotAffect 值为 cancellation_policy,则 room_type 存储桶的结果计数会减少到每个存储桶中的结果数,其中也可容纳 3 人,但 cancellation_policy 中存储桶的结果计数不受影响。

更多信息,请参阅跨分面过滤器排除示例。

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

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

适用以下限制:

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

The following examples use the sample data. The metadata results example demonstrates how to run a $searchMeta query with facet to retrieve only the metadata in the results. The metadata and search results example demonstrates how to run a $search query with facet and the $SEARCH_META aggregation variable to retrieve both the search and metadata results. The returnScope example demonstrates how to facet on nested fields in an array of objects dynamically indexed using the embeddedDocuments type.

要学习;了解更多信息,请参阅如何在MongoDB Search 中使用分面。

facet您可以通过我们的课程和视频,学习;了解有关MongoDB搜索中的 ( MongoDB搜索操作符)的更多信息。

要学习;了解有关在MongoDB Search 中使用分面的更多信息,请学习MongoDB University的MongoDB简介课程的 9 单元。1.5 小时单元包括MongoDB Search 概述以及有关创建MongoDB Search 索引、使用复合运算符运行$search 查询以及使用 facet 对结果进行分组的课程。

观看此视频,学习;了解如何在查询中创建和使用数字和字符串facet(MongoDB搜索运算符),对结果进行群组并检索分组中的结果计数。

时长:11 分钟

后退

存在

在此页面上