定义
facetfacet收集器按指定分面字段中的值或范围对结果进行分组,并返回每个组的计数。您可以将
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 } }
字段
字段 | 类型 | 必需? | 说明 |
|---|---|---|---|
| 文档 | 是 | 用于对每个分面(Facet)的数据进行分桶的信息。您必须指定至少一个分面定义。 |
| 文档 | 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>, } } } } }
选项
选项 | 类型 | 说明 | 必需? |
|---|---|---|---|
| int | 结果中要返回的最大分面(Facet)面类别数。值必须小于或等于 | no |
| 字符串 | 用于分面的字段路径。您可将被索引字段指定为 token。 | 是 |
| 字符串 | 分面类型。值必须是 | 是 |
例子
例子
以下示例将对 sample_mflix.movies 集合使用名为 default 的索引。集合中的 genres 字段被索引为 token 类型,而 year 字段被索引为 number 类型。
{ "mappings": { "dynamic": false, "fields": { "genres": { "type": "token" }, "year": { "type": "number" } } } }
该查询使用 $searchMeta 阶段在 movies 集合中的 year 字段内搜索从 2000 年到 2015 年的电影,并检索每种类型的电影数量。
1 db.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>" } } } } }
选项
选项 | 类型 | 说明 | 必需? |
|---|---|---|---|
| 数字数组 | 按升序排列的数值列表,而这些值指定了每个存储桶的边界。您必须指定至少两个边界,而这些边界应小于或等于 1000 (
| 是 |
| 字符串 | 附加存储桶的名称,用于对从操作符返回的不属于指定边界的文档进行计数。如果省略, MongoDB Search 也会包含不属于指定存储桶的分面(Facet)操作符符的结果,但不将其包含在任何存储桶计数中。 | no |
| 字符串 | 用于分面的字段路径。您可以指定一个已建立 number 类型索引的字段。 | 是 |
| 字符串 | 分面类型。值必须是 | 是 |
例子
例子
以下示例将对 sample_mflix.movies 集合使用名为 default 的索引。集合中的 year 字段被索引为 number 类型。
{ "mappings": { "dynamic": false, "fields": { "year": [ { "type": "number" } ] } } }
此查询使用 $searchMeta 阶段在 movies 集合中的 year 字段中搜索 1980 到 2000 年间的影片,并检索查询的元数据结果。此查询指定了三个存储桶:
1980,包括此存储桶的下限1990、1980存储桶的不含上限以及此存储桶的包含下限2000,1990存储桶的独占上限
该查询还会指定一个名为 other 的 default 存储桶,以便检索不属于任何指定边界的查询结果。
1 db.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>" } } } } }
选项
选项 | 类型 | 说明 | 必需? |
|---|---|---|---|
| 数字数组 | 指定每个存储桶边界的日期值列表。您必须指定:
每对相邻的值都充当存储桶的包含下限和不包含上限。 | 是 |
| 字符串 | 附加存储桶的名称,用于对从操作符返回的不属于指定边界的文档进行计数。如果省略, MongoDB Search 也会包含不属于指定存储桶的分面(Facet)操作符符的结果,但MongoDB Search 不会将这些结果包含在任何存储桶计数中。 | no |
| 字符串 | 用于分面的字段路径。您可将被索引字段指定为 date 类型。 | 是 |
| 字符串 | 分面类型。值必须是 | 是 |
例子
例子
以下示例将对 sample_mflix.movies 集合使用名为 default 的索引。集合中的 released 字段将索引为 date 类型。
{ "mappings": { "dynamic": false, "fields": { "released": [ { "type": "date" } ] } } }
此查询使用 $searchMeta 阶段在 movies 集合中的 released 字段中搜索 2000 到 2015 年间的影片,并检索查询字符串的元数据结果。此查询指定了四个存储桶:
2000-01-01,包括此存储桶的下限2005-01-01、2000-01-01存储桶的不含上限以及此存储桶的包含下限2010-01-01、2005-01-01存储桶的不含上限以及此存储桶的包含下限2015-01-01,2010-01-01存储桶的独占上限
该查询还会指定一个名为 other 的 default 存储桶,以便检索不属于任何指定边界的查询结果。
1 db.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 ]
要了解有关这些结果的更多信息,请参阅分面结果。
比较分面(Facet)的字段类型
与过时的类型(stringFacet、numberFacet、dateFacet)相比,更新的MongoDB搜索字段类型改进了支持分面(Facet)的功能。下表概述了功能上的主要区别:
分面(Facet)类别 | 更新的字段类型 | 过时的分面(Facet)类型 | 主要差异 |
|---|---|---|---|
字符串 | stringFacet(已过时) | 规范器支持: | |
数值 | numberFacet(已过时) | 数组支持: | |
Date | dateFacet(已过时) | 数组支持: |
注意
当为同一字段定义过时和更新的字段类型时,过时的分面(Facet)类型优先。示例,如果为字段同时定义了 token 和 stringFacet,分面(Facet)计算将使用 stringFacet 映射。
分面结果
对于分面(Facet)查询, MongoDB Search 返回定义的分面(Facet)名称到结果中该分面(Facet)的存储桶大量的映射。分面(Facet)结果文档包含 buckets 选项,它是分面(Facet)结果存储桶的大量。大量中的每个分面(Facet)存储桶文档都包含以下字段:
选项 | 类型 | 说明 |
|---|---|---|
| 对象 | 标识此方面存储桶的唯一标识符。此值与正在分面的数据类型相匹配。 |
| int | 此分面(Facet)存储桶中的文档计数。要学习;了解有关 |
多选分面
MongoDB Search 允许您同时查看和选择同一分面(Facet)中的多个存储桶。通常,选择分面(Facet)中的存储桶会根据该选择筛选搜索结果,并更改所有分面的计数。
例子
假设 sample_airbnb.listings集合的索引定义指定了以下字段的分面:
cancellation_policyroom_typeaccommodates
cancellation_policy分面(Facet)具有以下存储桶:
flexiblemoderatestrict_14_with_grace_periodsuper_strict_30super_strict_60
每个都有自己的结果计数。当您搜索moderate cancellation_policy 时,其他四个存储桶的计数将变为 0。此外,room_type 和 accommodates 分面中的存储桶计数减少为每个存储桶中也具有 flexible cancellation_policy 的结果数。
如果您需要更精细地控制分面如何影响搜索结果计数,请在分面查询中使用 doesNotAffect属性启用多选分面。这些分面仍会过滤结果,但查询不会更改其结果计数。
例子
考虑对 sample_airbnb.listings集合查询具有 moderate cancellation_policy 的文档。如果您将 doesNotAffect 值指定为 cancellation_policy,则 cancellation_policy分面(Facet)中存储桶的计数不会更改,但其他分面的存储桶的结果计数会减少,每个存储桶中的结果数也会减少一个 moderate cancellation_policy。
最后,对于具有多个分面的用例,限制哪些其他筛选器影响给定分面(Facet)可能很有用。为此,您可以在任何过滤的 doesNotAffect属性中指定任何分面(Facet)(包括其他字段上的分面)。这样您就可以一目了然地观察哪些选项或多或少地缩小了选项范围。
例子
考虑对 sample_airbnb.listings集合查询accommodates 值为 3 的文档。如果您指定的 doesNotAffect 值为 cancellation_policy,则 room_type 存储桶的结果计数会减少到每个存储桶中的结果数,其中也可容纳 3 人,但 cancellation_policy 中存储桶的结果计数不受影响。
SEARCH_META 聚合变量
当您使用 $search 阶段运行查询时, MongoDB Search 会将元数据结果存储在 $$SEARCH_META 变量中,并仅返回搜索结果。您可以在所有支持的聚合管道阶段中使用 $$SEARCH_META 变量来查看$search查询的元数据结果。
只有同时需要搜索结果和元数据结果时,MongoDB 才建议使用 $$SEARCH_META 变量。否则,请使用:
$search阶段以仅显示搜索结果。$searchMeta阶段以仅显式元数据结果。
限制
适用以下限制:
只能对单个字段运行分面查询。无法对字段群组运行分面查询。
示例
以下示例使用示例数据。元数据结果示例演示如何使用 $searchMeta 运行 facet 查询,以便仅检索结果中的元数据。元数据和搜索结果示例演示了如何使用 facet 和 $SEARCH_META 聚合变量运行 $search 查询,以便检索搜索结果和元数据结果。returnScope 示例演示了如何在使用 embeddedDocuments 类型动态索引的对象数组中对嵌套字段进行分面。
sample_mflix.movies 集合上的索引定义为要索引的字段指定了以下内容:
{ "mappings": { "dynamic": false, "fields": { "directors": { "type": "token" }, "year": { "type": "number" }, "released": { "type": "date" } } } }
以下查询搜索 2000 年 1 月 1 日至 2015 年 1 月 31 日之间上映的电影。它请求 directors 和 year 字段的元数据。
1 db.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 集合中的以下计数:
MongoDB搜索为查询返回的从 2000 年(含下边界)到 2015 年(不包括上边界)的电影数量
MongoDB搜索为查询返回的每位导演的电影数量
要了解有关这些结果的更多信息,请参阅分面结果。
sample_mflix.movies 集合上的索引定义为要索引的字段指定了以下内容:
{ "mappings": { "dynamic": false, "fields": { "genres": { "type": "token" }, "released": { "type": "date" } } } }
以下查询使用 $search 阶段搜索 1999 年 7 月 01 上映的电影。该查询包括 $facet 阶段,用于使用以下子管道阶段处理输入文档:
$project阶段,在docs输出字段中排除文件中除title和released字段以外的所有字段$limit阶段来执行以下操作:将
$search阶段的输出限制为2个文档在
meta输出字段中将输出限制为1个文档。
注意
限制必须很小,结果才能适合 16 MB 的文档。
$replaceWith阶段将存储在$$SEARCH_META变量中的元数据结果包含在meta输出字段中
该查询还包括用于添加 meta 字段的 $set 阶段。
注意
要查看以下查询的元数据结果, MongoDB Search 必须返回与查询匹配的文档。
1 db.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' released: ISODate('1999-07-01T00:00:00.000Z') 12 } 13 ], 14 meta: { 15 count: { lowerBound: Long('20878') }, 16 facet: { 17 genresFacet: { 18 buckets: [ 19 { _id: 'Drama', count: Long('12149') }, 20 { _id: 'Comedy', count: Long('6436') }, 21 { _id: 'Romance', count: Long('3274') }, 22 { _id: 'Crime', count: Long('2429') }, 23 { _id: 'Thriller', count: Long('2400') }, 24 { _id: 'Action', count: Long('2349') }, 25 { _id: 'Adventure', count: Long('1876') }, 26 { _id: 'Documentary', count: Long('1755') }, 27 { _id: 'Horror', count: Long('1432') }, 28 { _id: 'Biography', count: Long('1244') } 29 ] 30 } 31 } 32 } 33 } 34 ]
要了解有关这些结果的更多信息,请参阅分面结果。
sample_training.companies 集合上的索引定义将 funding_rounds 字段作为 embeddedDocuments 类型进行索引。它动态索引 funding_rounds 对象数组中的所有字段,并通过 storedSource 选项将 raised_currency_code 和 raised_amount 字段存储在funding_rounds 数组中。
{ "mappings": { "dynamic": false, "fields": { "funding_rounds": { "type": "embeddedDocuments", "dynamic": true, "storedSource": { "include": [ "raised_currency_code", "raised_amount" ] } } } } }
以下查询:
使用
text(MongoDB Search 操作符)搜索在USD中筹集的资金。使用 returnScope 选项将查询上下文设置为名为
funding_rounds的embeddedDocuments字段。要使用returnScope,查询:指定 returnStoredSource 选项,该选项是必需的,以返回存储的源字段。
funding_rounds对象数组中raised_amount字段上的分面。此查询指定了三个存储桶:5000000,包括此存储桶的下限
5250000,5000000 存储桶的不含上限以及此存储桶的包含下限
5500000,5250000 存储桶的独占上限
1 db.companies.aggregate([ 2 { 3 "$searchMeta": { 4 "returnStoredSource": true, 5 "returnScope": { 6 "path": "funding_rounds" 7 }, 8 "facet": { 9 "operator": { 10 "text": { 11 "path": "funding_rounds.raised_currency_code", 12 "query": "USD" 13 } 14 }, 15 "facets": { 16 "raisedAmountFacet": { 17 "type": "number", 18 "path": "funding_rounds.raised_amount", 19 "boundaries": [5000000, 5250000, 5500000] 20 } 21 } 22 } 23 } 24 } 25 ])
1 [ 2 { 3 count: { lowerBound: Long('5329') }, 4 facet: { 5 raisedAmountFacet: { 6 buckets: [ 7 { _id: 5000000, count: Long('251') }, 8 { _id: 5250000, count: Long('32') } 9 ] 10 } 11 } 12 } 13 ]
在前面的 MongoDB Search 结果中,分面计数基于嵌入的子文档,而不是父文档。
sample_airbnb.listingsAndReviews集合上的以下索引定义会自动为所有动态可索引字段编制索引,并为分面搜索配置 cancellation_policy、room_type 和 price 字段。
{ "mappings": { "dynamic": false, "fields": { "cancellation_policy": { "type": "token" }, "room_type": { "type": "token" }, "accommodates": { "type": "number" } } } }
以下查询使用 $searchMeta 阶段执行以下操作:
cancellation_policy、roomType和accommodates字段上的分面。cancellation_policy分面(Facet)具有以下存储桶:"strict_14_with_grace_period""moderate""flexible""super_strict_30""super_strict_60"
room_type分面(Facet)具有以下存储桶:"Entire home/apt""Private room""Shared room"
该查询将
accommodates分面(Facet)划分为多个存储桶:1,包括此存储桶的下限2、1存储桶的不含上限以及该存储桶的包含下限。4、2存储桶的不含上限以及该存储桶的包含下限。8,4存储桶的独占上限
compound对必须在 中包含文本 的列表执行new york citydescription操作符搜索,并在结果中筛选带有moderatecancellation_policy的列表。doesNotAffect设置可确保按moderatecancellation_policy进行筛选不会更改分面(Facet)中其他存储桶的计数;"strict_14_with_grace_period"、"flexible"、"super_strict_30"和"super_strict_60"的计数为非零值。
1 db.listingsAndReviews.aggregate([ 2 { 3 $searchMeta: { 4 facet: { 5 facets: { 6 accommodatesFacet: { 7 path: "accommodates", 8 type: "number", 9 boundaries: [1,2,4,8], 10 }, 11 cancellationFacet: { 12 path: "cancellation_policy", 13 type: "string", 14 }, 15 roomTypeFacet: { 16 path: "room_type", 17 type: "string", 18 } 19 }, 20 operator: { 21 compound: { 22 must: [ 23 { 24 text: { 25 path: "description", 26 query: "new york city", 27 }, 28 }, 29 ], 30 filter: [ 31 { 32 equals: { 33 path: "cancellation_policy", 34 value: "moderate", 35 doesNotAffect: 36 "cancellationFacet", 37 }, 38 }, 39 ], 40 }, 41 }, 42 }, 43 } 44 }, 45 ]
1 [ 2 { 3 count: { lowerBound: Long('531') }, 4 facet: { 5 accomodatesFacet: { 6 buckets: [ 7 { _id: "1", count: Long('25') }, 8 { _id: "2", count: Long('270') }, 9 { _id: "4", count: Long('204') }, 10 ] 11 }, 12 cancellationFacet: { 13 buckets: [ 14 { _id: "strict_14_with_grace_period", count: Long('849') }, 15 { _id: "moderate", count: Long('531') }, 16 { _id: "flexible", count: Long('380') }, 17 { _id: "super_strict_60", count: Long('25') } 18 { _id: "super_strict_30", count: Long('380') } 19 ] 20 }, 21 roomTypeFacet: { 22 buckets: [ 23 { _id: "Entire home/apt", count: Long('369') }, 24 { _id: "Private room", count: Long('159') }, 25 { _id: "Shared room", count: Long('3') }, 26 ] 27 } 28 } 29 } 30 ]
请注意,尽管对 moderate 值进行了查询筛选,但 cancellationFacet 中的存储桶计数并未减为零。
sample_airbnb.listingsAndReviews集合上的以下索引定义将为 cancellation_policy、room_type 和 price 字段编制索引,从而对它们启用分面搜索。
{ "mappings": { "dynamic": true, "fields": { "cancellation_policy": { "type": "token" }, "room_type": { "type": "token" }, "accommodates": { "type": "number" } } } }
以下查询:
搜索
description中包含new york city文本且cancellation_policy为moderate的列表。cancellation_policy、roomType和accommodates字段上的分面。每个
cancellation_policy和roomType分面都有三个存储桶,对应于这些字段在集合中的三个唯一值。该查询将accommodates分面(Facet)划分为多个存储桶:1,包括此存储桶的下限2、1存储桶的不含上限以及该存储桶的包含下限。4、2存储桶的不含上限以及该存储桶的包含下限。8,4存储桶的独占上限
将
compound.filter的equals操作符中的doesNotAffect属性设置为accommodatesFacet。这将从过滤中排除accommodates分面(Facet)内的存储桶。因此,对moderatecancellation_policy进行筛选会减少cancellation_policy分面(Facet)中其他存储桶的计数到0,并减少roomType分面(Facet)中存储桶的计数,但accommodates分面(Facet)未更改。这样,您就可以比较筛选对不同方面的影响。
1 db.listingsAndReviews.aggregate([ 2 { 3 $searchMeta: { 4 facet: { 5 facets: { 6 accommodatesFacet: { 7 path: "accommodates", 8 type: "number", 9 boundaries: [1,2,4,8], 10 }, 11 cancellationFacet: { 12 path: "cancellation_policy", 13 type: "string", 14 }, 15 roomTypeFacet: { 16 path: "room_type", 17 type: "string", 18 } 19 }, 20 operator: { 21 compound: { 22 must: [ 23 { 24 text: { 25 path: "description", 26 query: "new york city", 27 }, 28 }, 29 ], 30 filter: [ 31 { 32 equals: { 33 path: "cancellation_policy", 34 value: "moderate", 35 doesNotAffect: 36 "accommodatesFacet", 37 }, 38 }, 39 ], 40 }, 41 }, 42 }, 43 }, 44 }, 45 ]
1 [ 2 { 3 count: { lowerBound: Long('531') }, 4 facet: { 5 accomodatesFacet: { 6 buckets: [ 7 { _id: "1", count: Long('25') }, 8 { _id: "2", count: Long('270') }, 9 { _id: "4", count: Long('204') }, 10 ] 11 }, 12 cancellationFacet: { 13 buckets: [ 14 { _id: "flexible", count: Long('XXX') }, 15 { _id: "moderate", count: Long('531') }, 16 { _id: "strict_14_with_grace_period", count: Long('XXX') }, 17 ] 18 }, 19 roomTypeFacet: { 20 buckets: [ 21 { _id: "Entire home/apt", count: Long('369') }, 22 { _id: "Private room", count: Long('159') }, 23 { _id: "Shared room", count: Long('3') }, 24 ] 25 } 26 } 27 } 28 ]
继续学习
要学习;了解更多信息,请参阅如何在MongoDB Search 中使用分面。
facet您可以通过我们的课程和视频,学习;了解有关MongoDB搜索中的 ( MongoDB搜索操作符)的更多信息。
通过课程学习
要学习;了解有关在MongoDB Search 中使用分面的更多信息,请学习MongoDB University的MongoDB简介课程的 9 单元。1.5 小时单元包括MongoDB Search 概述以及有关创建MongoDB Search 索引、使用复合运算符运行$search 查询以及使用 facet 对结果进行分组的课程。
通过观看学习
观看此视频,学习;了解如何在查询中创建和使用数字和字符串facet(MongoDB搜索运算符),对结果进行群组并检索分组中的结果计数。
时长:11 分钟