Docs 菜单
Docs 主页
/ /

facet (MongoDB搜索操作符)

facet

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

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

如果在 embeddedDocuments字段类型定义中定义了 StoredSource,则可以将 returnScope returnStoredSource 结合使用,以对对象大量内的嵌套字段分面(Facet)。否则,您只能对根 embeddedDocuments 类型字段分面(Facet)。有关分面的示例:

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 支持以下类型的分面:

重要

字符串分面允许您根据指定字符串字段中最常见的字符串值缩小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]

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

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

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

日期分面允许您根据日期缩小搜索结果的范围。当您对数组或嵌入式文档中的日期进行分面(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 Search字段类型改进了支持分面的功能。下表概述了功能上的主要区别:

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

字符串

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

数值

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

Date

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

注意

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

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

选项
类型
说明

_id

对象

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

count

int

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

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

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

适用以下限制:

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

  • 您无法对集群上的分片分片的运行分面(Facet)查询。

以下示例使用示例数据。元数据结果示例演示了如何使用$searchMeta facet$searchfacet$SEARCH_METAreturnScope运行 查询,以便仅检索结果中的元数据。元数据和搜索结果示例演示了如何使用 和 聚合变量运行 查询,以检索搜索结果和元数据结果。 示例演示了如何对使用embeddedDocuments 类型动态索引的对象大量中的嵌套字段分面(Facet)。

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

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

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

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

时长:11 分钟

后退

存在

在此页面上