定义
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 分面(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_META 聚合变量
当您使用 $search 阶段运行查询时, MongoDB Search 会将元数据结果存储在 $$SEARCH_META 变量中,并仅返回搜索结果。您可以在所有支持的聚合管道阶段中使用 $$SEARCH_META 变量来查看$search查询的元数据结果。
只有同时需要搜索结果和元数据结果时,MongoDB 才建议使用 $$SEARCH_META 变量。否则,请使用:
$search阶段以仅显示搜索结果。$searchMeta阶段以仅显式元数据结果。
限制
适用以下限制:
只能对单个字段运行分面查询。无法对字段群组运行分面查询。
示例
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.
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分面分解为以下存储桶: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 分钟