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

对 Atlas Search 结果进行排序

在此页面上

  • Overview
  • sort 选项兼容性
  • sort 选项限制
  • 使用
  • 行为
  • Considerations
  • 语法
  • 示例
  • 索引定义
  • 日期搜索和排序
  • 数字搜索和排序
  • 字符串搜索和排序
  • 按 ObjectId 排序
  • 按 UUID 排序
  • 按空值排序
  • 对多类型数组进行排序
  • 按布尔值排序
  • 复合搜索和排序
  • 分面搜索和排序
  • 按分数排序

Atlas Search 允许您在 Atlas Search 索引中定义的字段中,按升序或降序对结果进行排序。您可以使用 sort 选项按以下字段类型进行排序:

  • boolean

  • date

  • number (整数、浮点数和 double 值)

  • objectId

  • uuid

  • string (索引为 词元类型)

您还可以按结果中文档的分数和 空值进行排序。

Atlas支持所有主要和次要MongoDB 5.0 及更高版本的非分片排序查询。分片排序查询可在 6.0 的所有主要版本以及 7.0 及更高版本的所有主要和次要版本上使用。

  • 不能对 embeddedDocuments 类型的字段进行排序。

  • 不能将 sort 选项与已弃用的 knnBeta 操作符一起使用。

要对 Atlas Search 结果进行排序,必须执行以下步骤:

  1. 在字段上创建 Atlas Search 索引,以便对结果进行排序。

    要对 booleandatenumberUUIDobjectId 字段排序,请使用动态或静态映射。要对字符串字段排序,您必须使用静态映射将字段索引为 token 类型。

  2. 使用sort选项针对您在索引中定义的字段创建并运行查询以进行排序。 要了解详情,请参阅语法。

sort 选项采用一个文档,该文档指定要作为排序依据的字段以及相应的排序顺序。对于支持的数据类型,Atlas Search 遵循 MongoDB 比较顺序。它像 BinData 一样处理 UUID 值。要了解更多信息,请参阅不存在的字段。

您可以指定以下排序顺序来对结果进行排序:

1

按升序排序。

当您按升序排序时,Atlas Search 将先返回值缺失的文档,然后再返回包含值的文档。

-1

按降序排序。

您还可以按分数升序或降序排序。 sort选项采用指定$meta表达式的文档,该表达式需要searchScore值。

例子

假设您的应用程序支持用户跳到搜索结果的最后一页。以下示例按分数升序对结果进行排序,以便分数最低的文档显示在结果的顶部:

sort: {score: {$meta: "searchScore", order: 1}}

当结果中的多个文档具有相同分数时,您还可以使用 sort 确保结果具有确定的顺序。例如,如果您按唯一字段(例如名为 lastUpdated 的日期字段,如下例所示)对结果进行排序,Atlas Search 将按确定的顺序返回分数相同的结果:

例子

sort: {score: {$meta: "searchScore"}, lastUpdated: 1}

但是,如果不指定唯一字段对结果进行排序,Atlas Search 返回的结果将按分数降序排序。Atlas Search 以任意顺序返回具有相同分数或值的结果。以下示例不按唯一字段对结果进行排序。

例子

sort: {score: {$meta: "searchScore"}}

要了解详情,请参阅对结果中的文档进行评分

Atlas Search 将数组展平以进行排序。

例子

请考虑以下数组:

[4, [1, [8,5], 9], 2]

Atlas Search 将前面的数组展平,类似于以下内容:

4, 1, 8, 5, 9, 2

对于升序排序,Atlas Search 使用 1 将数组与其他值进行比较。对于降序排序,Atlas Search 使用 9 将数组与其他值进行比较。

与数组内的元素进行比较时:

  • 对于升序排序,Atlas Search 比较数组的最小元素,或执行小于 (<) 比较。

    例子

    如果按编号升序排序,Atlas Search 会按以下顺序排列结果:

    -20
    [-3, 12] // <- -3 comes before 5.
    5
    [6, 18] // <- 6 comes after 5.
    13
    14
  • 对于降序排序,Atlas Search 比较数组的最大元素,或执行大于 (>) 比较。

    例子

    如果按数字降序排序,Atlas Search 会按以下顺序对结果进行排序:

    [6, 18] // <- 18 comes before 14.
    14
    13
    [-3, 12] // <- 12 comes after 13.
    5
    -20

对包含多个 BSON 类型值的大量字段进行排序时, Atlas Search会根据MongoDB 的默认比较和排序默认,从大量中选择一个有代表性的元素进行比较。

  • 对于升序排序, Atlas Search使用具有最低BSON类型的元素。

  • 对于降序排序, Atlas Search使用具有最高BSON类型的元素。

如果大量中有多个相同BSON类型的值,则应用所选类型的标准排序行为。

例子

请考虑以下数组:

[ 'foo', null, 15, true, false ]
  • 对于升序排序, Atlas Search使用null ,因为它是支持的最低BSON类型。

  • 对于降序排序, Atlas Search使用true ,因为它是大量中最高的BSON类型,并且Atlas Search将true 值排在false 值之上。

但是,如果您在noData: highest sort语法中设立 , Atlas Search会将 null 值和缺失值视为最高BSON类型。对于示例大量,以下行为适用:

  • 对于升序排序, Atlas Search使用15 ,因为它现在是大量中最低的BSON类型。

  • 对于降序排序, Atlas Search使用null ,因为它现在是大量中最高的BSON类型。

要学习;了解更多信息,请参阅按空值和缺失值排序。

有关示例,请参阅对多类型数组进行排序。

Atlas Search将 null 值视为等于缺失值和空值,并且在排序时,具有这些值的文档的顺序是不确定的。

默认情况下, Atlas Search遵循MongoDB比较和排序顺序,并将空值视为低于所有其他支持的BSON 类型。因此,升序排序时,空值出现在结果的顶部;降序排序时,空值出现在结果的底部。

要配置 null 值在结果中出现的位置,请在noData sort语法中指定 字段。noData字段采用以下值:

  • lowest (默认):在排序期间将空值设置为最低的BSON类型。升序排序时,将空值排序在结果的顶部;降序排序时,将空值排序在结果的底部。

  • highest:在排序期间将 null 值设置为最高BSON类型。在升序排序期间,将空值排序在结果的底部;在降序排序时,将空值排序在顶部。

注意

对具有包含 null 值或缺失值的多种类型的数组进行排序时,同样的行为也适用。

有关示例,请参阅按空值排序和对多类型数组排序。

要按嵌入式文档字段对父文档进行排序,必须执行以下操作:

  • 将嵌入式文档子字段的父项索引为文档类型。

  • 将嵌入文档中带有 string 值的子字段索引为标记类型。对于带有数字和日期值的子字段,启用动态映射可自动为这些字段编制索引。

Atlas Search 仅对父文档进行排序。 它不会对文档数组中的子字段进行排序。 有关示例,请参阅排序示例。

Atlas Search 索引最终是一致的,结果中返回的值可能与排序时使用的值不同。

此功能可优化使用 $search$limit 作为后续阶段的查询。如果 Atlas Search 需要对集合中的所有文档进行排序,响应可能会很慢。

Atlas Search 返回结果中所有文档的分数。但是,您可能会在得分较低的文档之后看到得分较高的文档,因为结果中文档的顺序是基于排序条件,除非您明确要求按分数排序。

sort 通过以下语法实现:

1{
2 "$search": {
3 "index": "<index name>", // optional, defaults to "default"
4 "<operator>": { // such as "text", "compound", or "phrase"
5 <operator-specification>
6 },
7 "sort": {
8 score: {$meta: "searchScore"}, // optional field
9 "<field-to-sort>": <sort-order>, // 1 or -1, or a document
10 ...
11 }
12 }
13}
Parameter
说明

score

<field-to-sort>

必需。 作为排序依据的字段的名称。

<sort-order>

必需。 确定排序顺序。 使用 1 进行升序排列,使用 -1 进行降序排列。

如果要指定 noData字段,请使用具有以下事务语法的文档:

"<field-to-sort>": {
order: 1 | -1, // required field
noData: "lowest" | "highest" // optional field
},
...

以下示例使用 sample_mflix.moviessample_airbnb.listingsAndReview 或名为 users 的自定义集合。


➤ 使用选择语言下拉菜单设置本节中示例的语言。


本页中的示例查询使用 sample_mflix.moviessample_airbnb.listingsAndReview或自定义集合。如果您在这些集合上创建以下索引,则可以针对索引字段运行示例查询。

movies 集合的索引定义将指定以下内容:

  • 索引 awards.wins 字段为:

  • 索引 released 字段为:

  • 索引 title 字段为:

    • token 排序类型

    • string 用于查询的类型

1{
2 "mappings": {
3 "dynamic": true,
4 "fields": {
5 "awards": {
6 "dynamic": false,
7 "fields": {
8 "wins": [
9 {
10 "type": "number"
11 }
12 ]
13 },
14 "type": "document"
15 },
16 "released": [
17 {
18 "type": "date"
19 }
20 ],
21 "title": [{
22 "type": "token"
23 }, {
24 "type": "string"
25 }]
26 }
27 }
28}

对于前面的索引定义,Atlas Search 创建一个名为 default 的索引,并在指定字段上使用静态映射

针对 sample_airbnb.listingsAndReviews 集合的示例查询使用了以下索引。索引定义指定了集合中字段的动态映射:

{
"mappings": {
"dynamic": true
}
}

users 集合包含以下文档:

db.users.insertMany([
{
"_id": 0,
"a": UUID("1a324de2-e34b-c87e-f2a1-42ce37ad74ed"),
"b": "hello",
"c": ObjectId("507f1f77bcf86cd799439011")
},
{
"_id": 1,
"a": UUID("3b241101-e2bb-4255-8caf-4136c566a962"),
"b": "hello",
"c": true
},
{
"_id": 2,
"a": UUID("dee11d4e-63c6-4d90-983c-5c9f1e79e96c"),
"b": "hello",
"c": "foo"
},
{
"_id": 3,
"b": "hello",
"c": UUID("3be11d4e-62cb-4e95-9a3c-5c9f1e56c732")
},
{
"_id": 4,
"a": UUID("d3c12e1c-c36e-25ed-7c3e-1e7f1e53c752"),
"b": "hello",
"c": null
},
{
"_id": 5,
"a": UUID("d73f181e-cdda-42b4-b844-4d6e172e9bc8"),
"b": "hello",
"c": []
}
{
"_id": 6,
"a": UUID("7eeddf21-b313-4a5c-81c2-c68915daa618"),
"b": "hello",
}
])

users 集合的索引定义将指定以下内容:

  • 动态索引除名为 c 的字段之外的所有字段。

  • 将名为 c 的字段静态索引为以下类型以进行排序:

    • token

    • uuid

    • objectId

    • boolean

1{
2 "mappings": {
3 "dynamic": true,
4 "fields": {
5 "c": [
6 { "type": "token" },
7 { "type": "uuid" },
8 { "type": "objectId" },
9 { "type": "boolean" },
10 { "type": "number" }
11 ]
12 }
13 }
14}

对于前面的集合,Atlas Search 会创建一个名为 default 的索引,并在指定字段上使用指定的映射。

以下查询显示了如何运行复合查询,并按日期字段对结果进行排序。它使用以下操作符:

  • 通配符操作符来搜索以 Summer 开头的电影标题。

  • 接近操作符,用于搜索 2014 年 4 月 18 日之前或之后五个月内发行的电影。

    注意

    对日期字段使用 pivot 时,其计量单位为毫秒。Atlas Search 会根据该日期字段与指定日期的接近程度为每个文档计算一个分数。要了解详情,请参阅 near

查询使用了下列管道阶段:

  • $search 阶段搜索 titlereleased 字段,然后按 released 字段降序对结果进行排序。

  • $limit 阶段将输出限制为 5 个结果。

  • $project 阶段到:

    • 排除除 titlereleased 之外的所有字段。

    • 添加名为 score 的字段。

1

将以下查询复制并粘贴到 Query Editor 中,然后单击 Query Editor 中的 Search 按钮。

[
{
$search: {
"compound": {
"filter": [{
"wildcard": {
"query": "Summer*",
"path": "title"
}
}],
"must": [{
"near": {
"pivot": 13149000000,
"path": "released",
"origin": ISODate("2014-04-18T00:00:00.000+00:00")
}
}]
},
"sort": {
"released": -1,
"title": 1
}
}
}
]
SCORE: 0.348105788230896 _id: "573a13f0f29313caabddaf7a"
countries: Array
runtime: 104
cast: Array
...
title: "Summer Nights"
...
released: 2015-01-28T00:00:00.000+00:00
...
SCORE: 0.5917375683784485 _id: "573a13e6f29313caabdc673b"
plot: "25-year-old Iiris and Karoliina have been best friends since childhood…"
genres: Array
runtime: 90
...
title: "Summertime"
...
released: 2014-08-01T00:00:00.000+00:00
...
SCORE: 0.9934720396995544 _id: "573a13eff29313caabdd760c"
plot: "Erik Sparrow is one of the lucky ones. He's got a good job. He's in a …"
genres: Array
runtime: 86
...
title: "Summer of Blood"
...
released: 2014-04-17T00:00:00.000+00:00
...
SCORE: 0.15982933342456818 _id: "573a13cff29313caabd8ab74"
plot: "The story of an adult and a teenage couple during a brief summer holid…"
genres: Array
countries: Array
...
title: "Summer Games"
...
released: 2012-02-08T00:00:00.000+00:00
...
SCORE: 0.13038821518421173 _id: "573a13cef29313caabd87f4e"
plot: "Summer of Goliath is a documentary/fiction hybrid that narrates variou…"
genres: Array
runtime: 78
...
title: "Summer of Goliath"
...
released: 2011-07-08T00:00:00.000+00:00
...
SCORE: 0.08124520629644394 _id: "573a13c7f29313caabd7608d"
plot: "A student tries to fix a problem he accidentally caused in OZ, a digit…"
genres: Array
runtime: 114
...
title: "Summer Wars"
...
released: 2009-08-01T00:00:00.000+00:00
SCORE: 0.0711759403347969 _id: "573a13bbf29313caabd54ee6"
plot: "The life of a public school epitomized by disobedient student Jonah Ta…"
genres: Array
runtime: 30
...
title: "Summer Heights High"
...
released: 2008-11-09T00:00:00.000+00:00
...
SCORE: 0.06951779872179031 _id: "573a13bff29313caabd5f935"
plot: "On his spring break at the seaside, with his wife and his four year ol…"
genres: Array
runtime: 102
...
title: "Summer Holiday"
...
released: 2008-09-19T00:00:00.000+00:00
...
SCORE: 0.05834990739822388 _id: "573a13c0f29313caabd628ac"
plot: "Kochi Uehara is a fourth grade student living in the suburb of Tokyo. …"
genres: Array
runtime: 138
...
title: "Summer Days with Coo"
...
released: 2007-07-28T00:00:00.000+00:00
...
SCORE: 0.056174591183662415 _id: "573a13b8f29313caabd4c1d0"
fullplot: "Country girl Yu Hong leaves her village, her family and her lover to s…"
genres: Array
runtime: 158
...
title: "Summer Palace"
...
released: 2007-04-18T00:00:00.000+00:00
...
2

Search Tester 可能不会显示其所返回文档的所有字段。要查看所有字段,包括在查询路径中指定的字段,请展开结果中的文档。

要在mongosh 中运行查询,请执行以下操作:

1db.movies.aggregate([
2{
3 $search: {
4 "index": "default",
5 "compound": {
6 "filter": [{
7 "wildcard": {
8 "query": "Summer*",
9 "path": "title"
10 }
11 }],
12 "must": [{
13 "near": {
14 "pivot": 13149000000,
15 "path": "released",
16 "origin": ISODate("2014-04-18T00:00:00.000+00:00")
17 }
18 }]
19 },
20 "sort": {
21 "released": -1
22 }
23 }
24},
25{
26 $limit: 5
27},
28{
29 $project: {
30 "_id": 0,
31 "title": 1,
32 "released": 1,
33 "score": {
34 "$meta": "searchScore"
35 }
36 }
37}])
[
{
title: 'Summer Nights',
released: ISODate("2015-01-28T00:00:00.000Z"),
score: 0.348105788230896
},
{
title: 'Summertime',
released: ISODate("2014-08-01T00:00:00.000Z"),
score: 0.5917375683784485
},
{
title: 'Summer of Blood',
released: ISODate("2014-04-17T00:00:00.000Z"),
score: 0.9934720396995544
},
{
title: 'Summer Games',
released: ISODate("2012-02-08T00:00:00.000Z"),
score: 0.15982933342456818
},
{
title: 'Summer of Goliath',
released: ISODate("2011-07-08T00:00:00.000Z"),
score: 0.13038821518421173
}
]

在MongoDB Compass中,从下拉列表中选择阶段并为该阶段添加查询,以配置以下每个管道阶段。单击 Add Stage 以添加其他阶段。

管道阶段
查询

$search

{
"index": "default",
"compound": {
"filter": [{
"wildcard": {
"query": "Summer*",
"path": "title"
}
}],
"must": [{
"near": {
"pivot": 13149000000,
"path": "released",
"origin": ISODate("2014-04-18T00:00:00.000+00:00")
}
}]
},
"sort": {
"released": -1
}
}

$limit

5

$project

{
_id: 0,
title: 1,
released: 1,
score: { $meta: "searchScore" }
}

如果启用了 Auto Preview,MongoDB Compass 将在 $limit 管道阶段旁边显示以下文档:

{
title: 'Summer Nights',
released: 2015-01-28T00:00:00.000+00:00,
score: 0.348105788230896
},
{
title: 'Summertime',
released: 2014-08-01T00:00:00.000+00:00,
score: 0.5917375683784485
},
{
title: 'Summer of Blood',
released: 2014-04-17T00:00:00.000+00:00,
score: 0.9934720396995544
},
{
title: 'Summer Games',
released: 2012-02-08T00:00:00.000+00:00,
score: 0.15982933342456818
},
{
title: 'Summer of Goliath',
released: 2011-07-08T00:00:00.000+00:00,
score: 0.13038821518421173
}
1
  1. Program.cs文件的内容替换为以下代码。

    1using MongoDB.Bson;
    2using MongoDB.Bson.Serialization.Attributes;
    3using MongoDB.Bson.Serialization.Conventions;
    4using MongoDB.Driver;
    5using MongoDB.Driver.Search;
    6
    7public class SortByStrings
    8{
    9 private const string MongoConnectionString = "<connection-string>";
    10
    11 public static void Main(string[] args)
    12 {
    13 // allow automapping of the camelCase database fields to our MovieDocument
    14 var camelCaseConvention = new ConventionPack { new CamelCaseElementNameConvention() };
    15 ConventionRegistry.Register("CamelCase", camelCaseConvention, type => true);
    16
    17 // connect to your Atlas cluster
    18 var mongoClient = new MongoClient(MongoConnectionString);
    19 var mflixDatabase = mongoClient.GetDatabase("sample_mflix");
    20 var moviesCollection = mflixDatabase.GetCollection<MovieDocument>("movies");
    21
    22
    23 // declare data for compound query
    24 var originDate = new DateTime(2014, 04, 18, 0, 0, 0, DateTimeKind.Utc);
    25
    26 // define search options
    27 var searchOptions = new SearchOptions<MovieDocument>()
    28 {
    29 Sort = Builders<MovieDocument>.Sort.Descending(movie => movie.Released),
    30 IndexName = "default"
    31 };
    32
    33 // define and run pipeline
    34 var results = moviesCollection.Aggregate()
    35 .Search(Builders<MovieDocument>.Search.Compound()
    36 .Filter(Builders<MovieDocument>.Search.Wildcard(movie => movie.Title, "Summer*"))
    37 .Must(Builders<MovieDocument>.Search.Near(movie => movie.Released, originDate, 13149000000)), searchOptions)
    38 .Project<MovieDocument>(Builders<MovieDocument>.Projection
    39 .Include(movie => movie.Released)
    40 .Include(movie => movie.Title)
    41 .Exclude(movie => movie.Id)
    42 .MetaSearchScore(movie => movie.Score))
    43 .Limit(5)
    44 .ToList();
    45
    46 // print results
    47 foreach (var movie in results)
    48 {
    49 Console.WriteLine(movie.ToJson());
    50 }
    51 }
    52}
    53
    54[BsonIgnoreExtraElements]
    55public class MovieDocument
    56{
    57 [BsonIgnoreIfDefault]
    58 public ObjectId Id { get; set; }
    59 public DateTime Released { get; set; }
    60 public string Title { get; set; }
    61 public double Score { get; set; }
    62}
  2. 指定 <connection-string>(代表的电子邮件地址)。

2
dotnet run Program.cs
{ "released" : ISODate("2015-01-28T00:00:00Z"), "title" : "Summer Nights", "score" : 0.348105788230896 }
{ "released" : ISODate("2014-08-01T00:00:00Z"), "title" : "Summertime", "score" : 0.59173756837844849 }
{ "released" : ISODate("2014-04-17T00:00:00Z"), "title" : "Summer of Blood", "score" : 0.99347203969955444 }
{ "released" : ISODate("2014-01-17T00:00:00Z"), "title" : "Summer in February", "score" : 0.62580311298370361 }
{ "released" : ISODate("2012-02-08T00:00:00Z"), "title" : "Summer Games", "score" : 0.15982933342456818 }
1
  1. 创建一个名为 sort-by-date.go 的新文件并粘贴以下代码:

    1package main
    2
    3import (
    4 "context"
    5 "fmt"
    6 "time"
    7
    8 "go.mongodb.org/mongo-driver/v2/bson"
    9 "go.mongodb.org/mongo-driver/v2/mongo"
    10 "go.mongodb.org/mongo-driver/v2/mongo/options"
    11)
    12
    13func main() {
    14 // connect to your Atlas cluster
    15 client, err := mongo.Connect(options.Client().ApplyURI("<connection-string"))
    16 if err != nil {
    17 panic(err)
    18 }
    19 defer client.Disconnect(context.TODO())
    20
    21 // set namespace
    22 collection := client.Database("sample_mflix").Collection("movies")
    23
    24 // define pipeline stages
    25 searchStage := bson.D{{Key: "$search", Value: bson.M{
    26 "index": "default",
    27 "compound": bson.M{
    28 "filter": bson.A{
    29 bson.M{
    30 "wildcard": bson.D{
    31 {Key: "path", Value: "title"},
    32 {Key: "query", Value: "Summer*"},
    33 }},
    34 },
    35 "must": bson.A{
    36 bson.M{
    37 "near": bson.M{
    38 "path": "released",
    39 "origin": time.Date(2014, time.April, 18, 0, 0, 0, 0, time.UTC),
    40 "pivot": 13149000000}},
    41 },
    42 },
    43 "sort": bson.D{{Key: "released", Value: -1}},
    44 }}}
    45
    46 limitStage := bson.D{{Key: "$limit", Value: 5}}
    47 projectStage := bson.D{{Key: "$project", Value: bson.D{{Key: "_id", Value: 0}, {Key: "title", Value: 1}, {Key: "released", Value: 1}, {Key: "score", Value: bson.D{{Key: "$meta", Value: "searchScore"}}}}}}
    48
    49 // run pipeline
    50 cursor, err := collection.Aggregate(context.TODO(), mongo.Pipeline{searchStage, limitStage, projectStage})
    51 if err != nil {
    52 panic(err)
    53 }
    54
    55 // print results
    56 var results []bson.D
    57 if err = cursor.All(context.TODO(), &results); err != nil {
    58 panic(err)
    59 }
    60 for _, result := range results {
    61 fmt.Println(result)
    62 }
    63}
  2. 指定 <connection-string>(代表的电子邮件地址)。

2
go run sort-by-date.go
[{title Summer Nights} {released 1422403200000} {score 0.348105788230896}]
[{title Summertime} {released 1406851200000} {score 0.5917375683784485}]
[{title Summer of Blood} {released 1397692800000} {score 0.9934720396995544}]
[{title Summer Games} {released 1328659200000} {score 0.15982933342456818}]
[{title Summer of Goliath} {released 1310083200000} {score 0.13038821518421173}]
1
  1. 创建一个名为 SortByDate.java 的新文件并粘贴以下代码:

    1import java.util.Arrays;
    2import java.util.List;
    3
    4import static com.mongodb.client.model.Aggregates.limit;
    5import static com.mongodb.client.model.Aggregates.project;
    6import static com.mongodb.client.model.Projections.*;
    7import com.mongodb.client.MongoClient;
    8import com.mongodb.client.MongoClients;
    9import com.mongodb.client.MongoCollection;
    10import com.mongodb.client.MongoDatabase;
    11import org.bson.Document;
    12
    13import java.time.Instant;
    14import java.util.Date;
    15
    16public class SortByDate {
    17 public static void main( String[] args ) {
    18 // define query
    19 Document agg =
    20 new Document("$search",
    21 new Document("index", "default")
    22 .append("compound",
    23 new Document("filter", Arrays.asList(new Document("wildcard",
    24 new Document("query", "Summer*")
    25 .append("path", "title"))))
    26 .append("must", Arrays.asList(new Document("near",
    27 new Document("pivot", 13149000000L)
    28 .append("path", "released")
    29 .append("origin", Date.from(Instant.parse("2014-04-18T00:00:00.000+00:00")))))))
    30 .append("sort", new Document("released", -1)));
    31
    32 // specify connection
    33 String uri = "<connection-string>";
    34
    35 // establish connection and set namespace
    36 try (MongoClient mongoClient = MongoClients.create(uri)) {
    37 MongoDatabase database = mongoClient.getDatabase("sample_mflix");
    38 MongoCollection<Document> collection = database.getCollection("movies");
    39 // run query and print results
    40 collection.aggregate(Arrays.asList(agg,
    41 limit(5),
    42 project(fields(exclude("_id"), include("title"), include("released"), computed("score", new Document("$meta", "searchScore"))))))
    43 .forEach(doc -> System.out.println(doc.toJson()));
    44 }
    45 }
    46}

    注意

    要在 Maven 环境中运行示例代码,请将以下代码添加到文件中的 import 语句上方。

    package com.mongodb.drivers;
  2. 指定 <connection-string>(代表的电子邮件地址)。

2
javac SortByDate.java
java SortByDate
{"title": "Summer Nights", "released": {"$date": "2015-01-28T00:00:00Z"}, "score": 0.348105788230896}
{"title": "Summertime", "released": {"$date": "2014-08-01T00:00:00Z"}, "score": 0.5917375683784485}
{"title": "Summer of Blood", "released": {"$date": "2014-04-17T00:00:00Z"}, "score": 0.9934720396995544}
{"title": "Summer Games", "released": {"$date": "2012-02-08T00:00:00Z"}, "score": 0.15982933342456818}
{"title": "Summer of Goliath", "released": {"$date": "2011-07-08T00:00:00Z"}, "score": 0.13038821518421173}
1
  1. 创建一个名为 SortByDate.kt 的新文件并粘贴以下代码:

    1import com.mongodb.client.model.Aggregates.limit
    2import com.mongodb.client.model.Aggregates.project
    3import com.mongodb.client.model.Projections.*
    4import com.mongodb.kotlin.client.coroutine.MongoClient
    5import kotlinx.coroutines.runBlocking
    6import org.bson.Document
    7import java.time.Instant
    8import java.util.*
    9
    10fun main() {
    11 // establish connection and set namespace
    12 val uri = "<connection-string>"
    13 val mongoClient = MongoClient.create(uri)
    14 val database = mongoClient.getDatabase("sample_mflix")
    15 val collection = database.getCollection<Document>("movies")
    16
    17 runBlocking {
    18 // define query
    19 val agg = Document(
    20 "\$search",
    21 Document("index", "default")
    22 .append(
    23 "compound",
    24 Document(
    25 "filter", listOf(
    26 Document(
    27 "wildcard",
    28 Document("query", "Summer*")
    29 .append("path", "title")
    30 )
    31 )
    32 )
    33 .append(
    34 "must", listOf(
    35 Document(
    36 "near",
    37 Document("pivot", 13149000000L)
    38 .append("path", "released")
    39 .append("origin", Date.from(Instant.parse("2014-04-18T00:00:00.000+00:00")))
    40 )
    41 )
    42 )
    43 )
    44 .append("sort", Document("released", -1))
    45 )
    46
    47 // run query and print results
    48 val resultsFlow = collection.aggregate<Document>(
    49 listOf(
    50 agg,
    51 limit(5),
    52 project(fields(
    53 excludeId(),
    54 include("title", "released"),
    55 computed("score", Document("\$meta", "searchScore"))
    56 ))
    57 )
    58 )
    59 resultsFlow.collect { println(it) }
    60 }
    61 mongoClient.close()
    62}
  2. 指定 <connection-string>(代表的电子邮件地址)。

2
kotlin SortByDate.kt
Document{{title=Summer Nights, released=Tue Jan 27 19:00:00 EST 2015, score=0.348105788230896}}
Document{{title=Summertime, released=Thu Jul 31 20:00:00 EDT 2014, score=0.5917375683784485}}
Document{{title=Summer of Blood, released=Wed Apr 16 20:00:00 EDT 2014, score=0.9934720396995544}}
Document{{title=Summer Games, released=Tue Feb 07 19:00:00 EST 2012, score=0.15982933342456818}}
Document{{title=Summer of Goliath, released=Thu Jul 07 20:00:00 EDT 2011, score=0.13038821518421173}}
1
  1. 创建一个名为 sort-by-date.js 的新文件并粘贴以下代码:

    1const { MongoClient } = require("mongodb");
    2
    3// Replace the uri string with your MongoDB deployments connection string.
    4const uri =
    5 "<connection-string>";
    6
    7const client = new MongoClient(uri);
    8
    9async function run() {
    10 try {
    11 await client.connect();
    12
    13 // set namespace
    14 const database = client.db("sample_mflix");
    15 const coll = database.collection("movies");
    16
    17 // define pipeline
    18 const agg = [
    19 {$search: {
    20 index: "default",
    21 compound: {
    22 filter: {wildcard: {query: "Summer*", path: "title"}},
    23 must: [{near: {path: "released", origin: new Date("2014-04-18T00:00:00.000Z"), pivot: 13149000000}}]
    24 },
    25 sort: { released: -1 }
    26 }},
    27 {$limit: 5},
    28 {$project: {_id: 0, title: 1, released: 1, score: {$meta: "searchScore"}}}
    29 ];
    30
    31 // run pipeline
    32 const result = await coll.aggregate(agg);
    33
    34 // print results
    35 await result.forEach((doc) => console.log(doc));
    36
    37 } finally {
    38 await client.close();
    39 }
    40}
    41run().catch(console.dir);
  2. 指定 <connection-string>(代表的电子邮件地址)。

2
node sort-by-date.js
{
title: 'Summer Nights',
released: 2015-01-28T00:00:00.000Z,
score: 0.348105788230896
}
{
title: 'Summertime',
released: 2014-08-01T00:00:00.000Z,
score: 0.5917375683784485
}
{
title: 'Summer of Blood',
released: 2014-04-17T00:00:00.000Z,
score: 0.9934720396995544
}
{
title: 'Summer Games',
released: 2012-02-08T00:00:00.000Z,
score: 0.15982933342456818
}
{
title: 'Summer of Goliath',
released: 2011-07-08T00:00:00.000Z,
score: 0.13038821518421173
}
1
  1. 创建一个名为 sort-by-date.py 的新文件并粘贴以下代码:

    1import datetime
    2import pymongo
    3
    4# connect to your Atlas cluster
    5client = pymongo.MongoClient('<connection-string>')
    6
    7# define pipeline
    8pipeline = [
    9 {'$search': {
    10 'index': 'default',
    11 'compound': {
    12 'filter': {'wildcard': {'query': 'Summer*', 'path': 'title'}},
    13 'must': {'near': {
    14 "path": "released",
    15 "origin": datetime.datetime(2014, 4, 18, 0, 0, 0, 0),
    16 "pivot": 13149000000
    17 }}},
    18 'sort': { 'released': -1 }}},
    19 {'$limit': 5},
    20 {'$project': {'_id': 0, 'title': 1, 'released': 1, 'score': {'$meta': 'searchScore'}}}
    21]
    22
    23# run pipeline
    24result = client['sample_mflix']['movies'].aggregate(pipeline)
    25
    26# print results
    27for i in result:
    28 print(i)
  2. 指定 <connection-string>(代表的电子邮件地址)。

2
python sort-by-date.py
{'title': 'Summer Nights', 'released': datetime.datetime(2015, 1, 28, 0, 0), 'score': 0.348105788230896}
{'title': 'Summertime', 'released': datetime.datetime(2014, 8, 1, 0, 0), 'score': 0.5917375683784485}
{'title': 'Summer of Blood', 'released': datetime.datetime(2014, 4, 17, 0, 0), 'score': 0.9934720396995544}
{'title': 'Summer Games', 'released': datetime.datetime(2012, 2, 8, 0, 0), 'score': 0.15982933342456818}
{'title': 'Summer of Goliath', 'released': datetime.datetime(2011, 7, 8, 0, 0), 'score': 0.13038821518421173}

以下查询演示如何按数值字段对结果进行排序。它使用范围操作符搜索赢得 10 个或更多奖项的电影,然后按数值字段值降序对结果进行排序。

查询使用了下列管道阶段:

  • $search 阶段搜索 awards.wins 字段,并按降序对结果排序。

  • $limit 阶段将输出限制为 5 个结果。

  • $project 阶段排除 titleawards.wins 以外的所有字段。

1

将以下查询复制并粘贴到 Query Editor 中,然后点击 Query Editor 中的 Search 按钮。

[
{
"$search": {
"range": {
"path": "awards.wins",
"gte": 10
},
"sort": {
"awards.wins": -1,
}
}
}
]
SCORE: 1 _id: "573a13d5f29313caabd9cae7"
fullplot: "Based on an incredible true story of one man's fight for survival and …"
imdb: Object
...
year: 2013
...
awards: Object
wins: 267
...
...
SCORE: 1 _id: "573a13c7f29313caabd74a4d"
fullplot: "Dr. Ryan Stone (Sandra Bullock) is a brilliant medical engineer on her…"
imdb: Object
...
year: 2013
...
awards: Object
wins: 231
...
...
SCORE: 1 _id: "573a13cbf29313caabd808d2"
fullplot: "Dr. Ryan Stone (Sandra Bullock) is a brilliant medical engineer on her…"
imdb: Object
...
year: 2013
...
awards: Object
wins: 231
...
...
SCORE: 1 _id: “573a13dff29313caabdb7adb”"
fullplot: "Actor Riggan Thomson is most famous for his movie role from over twent…"
imdb: Object
...
year: 2014
...
awards: Object
wins: 210
...
...
SCORE: 1 _id: "573a13bef29313caabd5c06c"
plot: "The life of Mason, from early childhood to his arrival at college."
imdb: Object
...
runtime: 165
...
awards: Object
wins: 185
...
...
SCORE: 1 _id: "573a139ef29313caabcfbd6a"
fullplot: "While Frodo & Sam continue to approach Mount Doom to destroy the One R…"
imdb: Object
...
year: 2003
...
awards: Object
wins: 175
...
...
SCORE: 1 _id: "573a13b5f29313caabd447f5"
plot: "In rural Texas, welder and hunter Llewelyn Moss discovers the remains …"
imdb: Object
...
year: 2007
...
awards: Object
wins: 172
...
...
SCORE: 1 _id: "573a13c3f29313caabd68d9f"
plot: "On a fall night in 2003, Harvard undergrad and computer programming ge…"
imdb: Object
...
year: 2010
...
awards: Object
wins: 171
...
...
SCORE: 1 _id: "573a13c5f29313caabd6ee61"
fullplot: "Dom Cobb is a skilled thief, the absolute best in the dangerous art of…"
imdb: Object
...
year: 2010
...
awards: Object
wins: 162
...
...
SCORE: 1 _id: "573a13bdf29313caabd58fd3"
plot: "The story of Jamal Malik, an 18 year-old orphan from the slums of Mumb…"
imdb: Object
...
year: 2008
...
awards: Object
wins: 161
...
...
2

Search Tester 可能不会显示其所返回文档的所有字段。要查看所有字段,包括在查询路径中指定的字段,请展开结果中的文档。

要在mongosh 中运行查询,请执行以下操作:

1db.movies.aggregate([
2 {
3 "$search": {
4 "range": {
5 "path": "awards.wins",
6 "gte": 10
7 },
8 "sort": {
9 "awards.wins": -1,
10 }
11 }
12 },
13 {
14 $limit: 5
15 },
16 {
17 "$project": {
18 "_id": 0,
19 "title": 1,
20 "awards.wins": 1
21 }
22 }
23])
[
{
title: '12 Years a Slave',
awards: { wins: 267 }
},
{
title: 'Gravity',
awards: { wins: 231 }
},
{
title: 'Gravity',
awards: { wins: 231 }
},
{
title: 'Birdman: Or (The Unexpected Virtue of Ignorance)',
awards: { wins: 210 }
},
{
title: 'Boyhood',
awards: { wins: 185 }
}
]

在MongoDB Compass中,从下拉列表中选择阶段并为该阶段添加查询,以配置以下每个管道阶段。单击 Add Stage 以添加其他阶段。

管道阶段
查询

$search

{
index: "default",
"range": {
"path": "awards.wins",
"gte": 10
},
"sort": {
"awards.wins": -1,
}
}

$limit

5

$project

{
title: 1,
released: 1,
year: 1
}

如果启用了 Auto Preview,MongoDB Compass 将在 $limit 管道阶段旁边显示以下文档:

[
{
title: '12 Years a Slave',
awards: { wins: 267 }
},
{
title: 'Gravity',
awards: { wins: 231 }
},
{
title: 'Gravity',
awards: { wins: 231 }
},
{
title: 'Birdman: Or (The Unexpected Virtue of Ignorance)',
awards: { wins: 210 }
},
{
title: 'Boyhood',
awards: { wins: 185 }
}
]
1
  1. 在您的项目中,将 Program.cs文件的内容替换为以下代码。

    1using MongoDB.Bson;
    2using MongoDB.Bson.Serialization.Attributes;
    3using MongoDB.Bson.Serialization.Conventions;
    4using MongoDB.Driver;
    5using MongoDB.Driver.Search;
    6
    7public class SortByNumbers
    8{
    9 private const string MongoConnectionString = "<connection-string>";
    10
    11 public static void Main(string[] args)
    12 {
    13 // allow automapping of the camelCase database fields to our MovieDocument
    14 var camelCaseConvention = new ConventionPack { new CamelCaseElementNameConvention() };
    15 ConventionRegistry.Register("CamelCase", camelCaseConvention, type => true);
    16
    17 // connect to your Atlas cluster
    18 var mongoClient = new MongoClient(MongoConnectionString);
    19 var mflixDatabase = mongoClient.GetDatabase("sample_mflix");
    20 var moviesCollection = mflixDatabase.GetCollection<MovieDocument>("movies");
    21
    22 // define search options
    23 var searchOptions = new SearchOptions<MovieDocument>()
    24 {
    25 Sort = Builders<MovieDocument>.Sort.Descending(movies => movies.Awards.Wins),
    26 IndexName = "default"
    27 };
    28
    29 // define and run pipeline
    30 var results = moviesCollection.Aggregate()
    31 .Search(
    32 Builders<MovieDocument>.Search.Range(movie => movie.Awards.Wins, SearchRangeBuilder.Gte(10)), searchOptions)
    33 .Project<MovieDocument>(Builders<MovieDocument>.Projection
    34 .Exclude(movie => movie.Id)
    35 .Include(movie => movie.Title)
    36 .Include(movie => movie.Awards.Wins))
    37 .Limit(5)
    38 .ToList();
    39
    40 // print results
    41 foreach (var movie in results)
    42 {
    43 Console.WriteLine(movie.ToJson());
    44 }
    45 }
    46}
    47
    48[BsonIgnoreExtraElements]
    49public class MovieDocument
    50{
    51 [BsonIgnoreIfDefault]
    52 public ObjectId Id { get; set; }
    53 public string Title { get; set; }
    54 public Award Awards { get; set; }
    55}
    56
    57public class Award
    58{
    59 [BsonIgnoreIfDefault]
    60 public int Wins { get; set; }
    61}
  2. 指定 <connection-string>(代表的电子邮件地址)。

2
dotnet run Program.cs
{ "title" : "12 Years a Slave", "awards" : { "wins" : 267 } }
{ "title" : "Gravity", "awards" : { "wins" : 231 } }
{ "title" : "Gravity", "awards" : { "wins" : 231 } }
{ "title" : "Birdman: Or (The Unexpected Virtue of Ignorance)", "awards" : { "wins" : 210 } }
{ "title" : "Boyhood", "awards" : { "wins" : 185 } }
1
  1. 创建一个名为 sort-by-numbers.go 的新文件并粘贴以下代码:

    1package main
    2
    3import (
    4 "context"
    5 "fmt"
    6
    7 "go.mongodb.org/mongo-driver/v2/bson"
    8 "go.mongodb.org/mongo-driver/v2/mongo"
    9 "go.mongodb.org/mongo-driver/v2/mongo/options"
    10)
    11
    12func main() {
    13 // connect to your Atlas cluster
    14 client, err := mongo.Connect(options.Client().ApplyURI("<connection-string>"))
    15 if err != nil {
    16 panic(err)
    17 }
    18 defer client.Disconnect(context.TODO())
    19
    20 // set namespace
    21 collection := client.Database("sample_mflix").Collection("movies")
    22
    23 // define pipeline stages
    24 searchStage := bson.D{{Key: "$search", Value: bson.D{
    25 {Key: "index", Value: "default"},
    26 {Key: "range", Value: bson.D{
    27 {Key: "path", Value: "awards.wins"},
    28 {Key: "gte", Value: 10},
    29 }},
    30 {Key: "sort", Value: bson.D{{Key: "awards.wins", Value: -1}}},
    31 }}}
    32 limitStage := bson.D{{Key: "$limit", Value: 5}}
    33 projectStage := bson.D{{Key: "$project", Value: bson.D{{Key: "title", Value: 1}, {Key: "awards.wins", Value: 1}, {Key: "_id", Value: 0}}}}
    34
    35 // run pipeline
    36 cursor, err := collection.Aggregate(context.TODO(), mongo.Pipeline{searchStage, limitStage, projectStage})
    37 if err != nil {
    38 panic(err)
    39 }
    40
    41 // print results
    42 var results []bson.D
    43 if err = cursor.All(context.TODO(), &results); err != nil {
    44 panic(err)
    45 }
    46 for _, result := range results {
    47 fmt.Println(result)
    48 }
    49}
  2. 指定 <connection-string>(代表的电子邮件地址)。

2
go run sort-by-numbers.go
[{title 12 Years a Slave} {awards [{wins 267}]}]
[{title Gravity} {awards [{wins 231}]}]
[{title Gravity} {awards [{wins 231}]}]
[{title Birdman: Or (The Unexpected Virtue of Ignorance)} {awards [{wins 210}]}]
[{title Boyhood} {awards [{wins 185}]}]
1
  1. 创建一个名为 SortByNumbers.java 的新文件并粘贴以下代码:

    1import java.util.Arrays;
    2
    3import static com.mongodb.client.model.Aggregates.limit;
    4import static com.mongodb.client.model.Aggregates.project;
    5import static com.mongodb.client.model.Projections.excludeId;
    6import static com.mongodb.client.model.Projections.fields;
    7import static com.mongodb.client.model.Projections.include;
    8import com.mongodb.client.MongoClient;
    9import com.mongodb.client.MongoClients;
    10import com.mongodb.client.MongoCollection;
    11import com.mongodb.client.MongoDatabase;
    12import org.bson.Document;
    13
    14public class SortByNumbers {
    15 public static void main( String[] args ) {
    16 // define query
    17 Document agg =
    18 new Document("$search",
    19 new Document("index", "default")
    20 .append("range",
    21 new Document("path", "awards.wins")
    22 .append("gte", 10L))
    23 .append("sort",
    24 new Document("awards.wins", -1L)));
    25
    26 // specify connection
    27 String uri = "<connection-string>";
    28
    29 // establish connection and set namespace
    30 try (MongoClient mongoClient = MongoClients.create(uri)) {
    31 MongoDatabase database = mongoClient.getDatabase("sample_mflix");
    32 MongoCollection<Document> collection = database.getCollection("movies");
    33
    34 // run query and print results
    35 collection.aggregate(Arrays.asList(agg,
    36 limit(5),
    37 project(fields(excludeId(), include("title"), include("awards.wins")))))
    38 .forEach(doc -> System.out.println(doc.toJson()));
    39 }
    40 }
    41}

    注意

    要在 Maven 环境中运行示例代码,请将以下代码添加到文件中的 import 语句上方。

    package com.mongodb.drivers;
  2. 指定 <connection-string>(代表的电子邮件地址)。

2
javac SortByNumbers.java
java SortByNumbers
{"title": "12 Years a Slave", "awards": {"wins": 267}}
{"title": "Gravity", "awards": {"wins": 231}}
{"title": "Gravity", "awards": {"wins": 231}}
{"title": "Birdman: Or (The Unexpected Virtue of Ignorance)", "awards": {"wins": 210}}
{"title": "Boyhood", "awards": {"wins": 185}}
1
  1. 创建一个名为 SortByNumbers.kt 的新文件并粘贴以下代码:

    1import com.mongodb.client.model.Aggregates.limit
    2import com.mongodb.client.model.Aggregates.project
    3import com.mongodb.client.model.Projections.*
    4import com.mongodb.kotlin.client.coroutine.MongoClient
    5import kotlinx.coroutines.runBlocking
    6import org.bson.Document
    7
    8fun main() {
    9 // establish connection and set namespace
    10 val uri = "<connection-string>"
    11 val mongoClient = MongoClient.create(uri)
    12 val database = mongoClient.getDatabase("sample_mflix")
    13 val collection = database.getCollection<Document>("movies")
    14
    15 runBlocking {
    16 // define query
    17 val agg = Document(
    18 "\$search",
    19 Document("index", "default")
    20 .append(
    21 "range",
    22 Document("path", "awards.wins")
    23 .append("gte", 10L)
    24 )
    25 .append(
    26 "sort",
    27 Document("awards.wins", -1L)
    28 )
    29 )
    30
    31 // run query and print results
    32 val resultsFlow = collection.aggregate<Document>(
    33 listOf(
    34 agg,
    35 limit(5),
    36 project(fields(
    37 excludeId(),
    38 include("title", "awards.wins")
    39 ))
    40 )
    41 )
    42 resultsFlow.collect { println(it) }
    43 }
    44 mongoClient.close()
    45}
  2. 指定 <connection-string>(代表的电子邮件地址)。

2
kotlin SortByNumbers.kt
Document{{title=12 Years a Slave, awards=Document{{wins=267}}}}
Document{{title=Gravity, awards=Document{{wins=231}}}}
Document{{title=Gravity, awards=Document{{wins=231}}}}
Document{{title=Birdman: Or (The Unexpected Virtue of Ignorance), awards=Document{{wins=210}}}}
Document{{title=Boyhood, awards=Document{{wins=185}}}}
1
  1. 创建一个名为 sort-by-numbers.js 的新文件并粘贴以下代码:

    1const { MongoClient } = require("mongodb");
    2
    3// Replace the uri string with your MongoDB deployments connection string.
    4const uri =
    5 "<connection-string>";
    6
    7const client = new MongoClient(uri);
    8
    9async function run() {
    10 try {
    11 await client.connect();
    12
    13 // set namespace
    14 const database = client.db("sample_mflix");
    15 const coll = database.collection("movies");
    16
    17 // define pipeline
    18 const agg = [
    19 {
    20 '$search': {
    21 'index': 'default',
    22 'range': {
    23 'path': 'awards.wins',
    24 'gte': 10
    25 },
    26 'sort': {
    27 'awards.wins': -1
    28 }
    29 }
    30 }, {
    31 '$limit': 5
    32 }, {
    33 '$project': {
    34 '_id': 0,
    35 'title': 1,
    36 'awards.wins': 1
    37 }
    38 }
    39 ];
    40
    41 // run pipeline
    42 const result = await coll.aggregate(agg);
    43
    44 // print results
    45 await result.forEach((doc) => console.log(doc));
    46
    47 } finally {
    48 await client.close();
    49 }
    50}
    51run().catch(console.dir);
  2. 指定 <connection-string>(代表的电子邮件地址)。

2
node sort-by-numbers.js
{ title: '12 Years a Slave', awards: { wins: 267 } }
{ title: 'Gravity', awards: { wins: 231 } }
{ title: 'Gravity', awards: { wins: 231 } }
{
title: 'Birdman: Or (The Unexpected Virtue of Ignorance)',
awards: { wins: 210 }
}
{ title: 'Boyhood', awards: { wins: 185 } }
1
  1. 创建一个名为 sort-by-numbers.py 的新文件并粘贴以下代码:

    1import pymongo
    2
    3# connect to your Atlas cluster
    4client = pymongo.MongoClient('<connection-string>')
    5
    6# define pipeline
    7pipeline = [
    8 {
    9 '$search': {
    10 'index': 'default',
    11 'range': {
    12 'path': 'awards.wins',
    13 'gte': 10
    14 },
    15 'sort': {
    16 'awards.wins': -1
    17 }
    18 }
    19 }, {
    20 '$limit': 5
    21 }, {
    22 '$project': {'_id': 0, 'title': 1, 'awards.wins': 1
    23 }
    24 }
    25]
    26
    27# run pipeline
    28result = client['sample_mflix']['movies'].aggregate(pipeline)
    29
    30# print results
    31for i in result:
    32 print(i)
  2. 指定 <connection-string>(代表的电子邮件地址)。

2
python sort-by-numbers.py
{'title': '12 Years a Slave', 'awards': {'wins': 267}}
{'title': 'Gravity', 'awards': {'wins': 231}}
{'title': 'Gravity', 'awards': {'wins': 231}}
{'title': 'Birdman: Or (The Unexpected Virtue of Ignorance)', 'awards': {'wins': 210}}
{'title': 'Boyhood', 'awards': {'wins': 185}}

sample_mflix.movies 命名空间的以下查询使用 $search 阶段执行以下操作:

  • 搜索标题中包含“country”一词的电影。

  • 使用 sort 选项以升序排列结果。

该查询使用$limit阶段将输出限制为5文档。 它还使用$project阶段执行以下操作:

  • 忽略结果中除 title 之外的所有字段。

  • 添加名为 score 的字段。

db.movies.aggregate([
{
"$search": {
"text": {
"path": "title",
"query": "country"
},
"sort": {
"title": 1
}
}
},
{
"$limit": 5
},
{
"$project": {
"_id": 0,
"title": 1,
"score": { "$meta": "searchScore" }
}
}
])
[
{ title: 'A Country Called Home', score: 2.536633253097534 },
{ title: 'A Month in the Country', score: 2.258953094482422 },
{ title: 'A Quiet Place in the Country', score: 2.0360684394836426 },
{ title: 'A Sunday in the Country', score: 2.258953094482422 },
{ title: 'Another Country', score: 3.3635599613189697 }
]

以下查询演示如何按字符串字段查询结果并对其进行排序。它搜索以 PrancePrince 开头的标题,并按 title 字段升序对结果进行排序。

查询使用了下列管道阶段:

  • $search 使用带有通配符操作符的 should 子句搜索 title 字段,搜索以 PrancePrince 开头的名称。该查询还指定结果必须按 title 字段升序排序。

  • $limit 阶段将输出限制为 5 个结果。

  • $project 阶段到:

    • 排除 title 以外的所有字段。

    • 添加名为 score 的字段。

[
{
$search: {
"compound": {
"should": [{
"wildcard": {
"query": ["Prance*"],
"path": "title",
"allowAnalyzedField": true
}
},
{
"wildcard": {
"query": ["Prince*"],
"path": "title",
"allowAnalyzedField": true
}
}]
},
"sort": {
"title": 1
}
}
}
]
SCORE: 1 _id: "573a1398f29313caabceb98e"
plot: "A farm girl nurses a wounded reindeer she believes is one of Santa's, …"
genres: Array
runtime: 103
...
title: "Prancer"
...
SCORE: 1 _id: "573a13a5f29313caabd14f54"
plot: "Preteen brothers from a broken marriage live with their mother, Denise…"
genres: Array
runtime: 91
...
title: "Prancer Returns"
...
SCORE: 1 _id: "573a13f5f29313caabde3755"
plot: "A troubled teenager attempts to conquer the love of his life by becomi…"
genres: Array
runtime: 78
...
title: "Prince"
...
SCORE: 1 _id: "573a13d8f29313caabda665f"
fullplot: "Two highway road workers spend the summer of 1988 away from their city…"
imdb: Object
year: 2013
...
title: "Prince Avalanche"
...
SCORE: 1 _id: "573a13bdf29313caabd5898a"
plot: "A New York street drama about the lives of immigrants in America seeki…"
genres: Array
runtime: 70
...
title: "Prince of Broadway"
...
SCORE: 1 _id: "573a1398f29313caabcea967"
fullplot: "A sinister secret has been kept in the basement of an abandoned Los An…"
imdb: Object
year: 1987
...
title: "Prince of Darkness"
...
SCORE: 1 _id: "573a1393f29313caabcde40d"
plot: "An unscrupulous agent for the Borgias suffers a change of heart when a…"
genres: Array
runtime: 107
...
title: "Princess of Foxes"
...
SCORE: 1 _id: "573a13b5f29313caabd43816"
plot: "A young fugitive prince and princess must stop a villain who unknowing…"
genres: Array
runtime: 116
...
title: "Prince of Persia: The Sands of Time"
...
SCORE: 1 _id: "573a1397f29313caabce8081"
plot: "A New York City narcotics detective reluctantly agrees to cooperate wi…"
genres: Array
runtime: 167
...
title: "Prince of the City"
...
SCORE: 1 _id: "573a13a2f29313caabd0a767"
plot: "Six old-style funny silhouetted fairy tales for not so-old-style peopl…"
genres: Array
runtime: 70
...
title: "Princes and Princesses"
...

Atlas Search 结果包含电影片名以 PrancePrince 开头的文档。Atlas Search 返回片名为 Prance 后跟Prince 的电影,因为 Atlas Search 按title 字段升序对文档进行排序。

Search Tester 可能不会显示其所返回文档的所有字段。要查看所有字段,包括在查询路径中指定的字段,请展开结果中的文档。

1db.movies.aggregate([{
2 $search: {
3 "index": "default",
4 "compound": {
5 "should": [{
6 "wildcard": {
7 "query": ["Prance*"],
8 "path": "title",
9 "allowAnalyzedField": true
10 }
11 },
12 {
13 "wildcard": {
14 "query": ["Prince*"],
15 "path": "title",
16 "allowAnalyzedField": true
17 }
18 }]
19 },
20 "sort": {
21 "title": 1
22 }
23 }},
24 {
25 $limit: 5
26 },
27 {
28 $project: {
29 "_id": 0,
30 "title": 1,
31 "score": { "$meta": "searchScore" }
32 }
33 }
34])
[
{ title: 'Prancer', score: 1 },
{ title: 'Prancer Returns', score: 1 },
{ title: 'Prince', score: 1 },
{ title: 'Prince Avalanche', score: 1 },
{ title: 'Prince of Broadway', score: 1 }
]

Atlas Search 结果包含电影片名以 PrancePrince 开头的文档。Atlas Search 返回片名为 Prance 后跟Prince 的电影,因为 Atlas Search 按title 字段升序对文档进行排序。

管道阶段
查询

$search

{
compound: {
should: [{
wildcard: {
query: "Prance*",
path: 'title',
allowAnalyzedField: true
}},
{
wildcard: {
query: "Prince*",
path: 'title',
allowAnalyzedField: true
}
}]
},
sort: {
title: 1
}
}

$limit

5

$project

{
_id: 0,
title: 1,
score: { $meta: "searchScore" }
}

如果启用了 Auto Preview,MongoDB Compass 将在 $project 管道阶段旁边显示以下文档:

{
title: 'Prancer',
score: 1
},
{
title: 'Prancer Returns',
score: 1
},
{
title: 'Prince',
score: 1
},
{
title: 'Prince Avalanche',
score: 1
},
{
title: 'Prince of Boradway',
score: 1
}

Atlas Search 结果包含电影片名以 PrancePrince 开头的文档。Atlas Search 返回片名为 Prance 后跟Prince 的电影,因为 Atlas Search 按title 字段升序对文档进行排序。

此代码示例将执行以下任务:

  • 导入mongodb包和依赖项。

  • 建立与您的 Atlas 集群的连接。

  • 查询使用了下列管道阶段:

    • $search 使用带有通配符操作符的 should 子句搜索 title 字段,搜索以 PrancePrince 开头的名称。该查询还指定结果必须按 title 字段升序排序。

    • $limit 阶段将输出限制为 5 个结果。

    • $project 阶段到:

      • 排除 title 以外的所有字段。

      • 添加名为 score 的字段。

  • 遍历游标以打印与查询匹配的文档。

1using MongoDB.Bson;
2using MongoDB.Bson.Serialization.Attributes;
3using MongoDB.Bson.Serialization.Conventions;
4using MongoDB.Driver;
5using MongoDB.Driver.Search;
6
7public class SortByStrings
8{
9 private const string MongoConnectionString = "<connection-string>";
10
11 public static void Main(string[] args)
12 {
13 // allow automapping of the camelCase database fields to our MovieDocument
14 var camelCaseConvention = new ConventionPack { new CamelCaseElementNameConvention() };
15 ConventionRegistry.Register("CamelCase", camelCaseConvention, type => true);
16
17 // connect to your Atlas cluster
18 var mongoClient = new MongoClient(MongoConnectionString);
19 var mflixDatabase = mongoClient.GetDatabase("sample_mflix");
20 var moviesCollection = mflixDatabase.GetCollection<MovieDocument>("movies");
21
22 // define search options
23 var searchOptions = new SearchOptions<MovieDocument>()
24 {
25 Sort = Builders<MovieDocument>.Sort.Ascending(movie => movie.Title),
26 IndexName = "default"
27 };
28
29 // define and run pipeline
30 var results = moviesCollection.Aggregate()
31 .Search(Builders<MovieDocument>.Search.Compound()
32 .Should(Builders<MovieDocument>.Search.Wildcard(movie => movie.Title, "Prance*", true ))
33 .Should(Builders<MovieDocument>.Search.Wildcard(movie => movie.Title, "Prince*" )), searchOptions)
34 .Project<MovieDocument>(Builders<MovieDocument>.Projection
35 .Include(movie => movie.Title)
36 .Exclude(movie => movie.Id)
37 .MetaSearchScore(movie => movie.Score))
38 .Limit(5)
39 .ToList();
40
41 // print results
42 foreach (var movie in results)
43 {
44 Console.WriteLine(movie.ToJson());
45 }
46 }
47}
48
49[BsonIgnoreExtraElements]
50public class MovieDocument
51{
52 [BsonIgnoreIfDefault]
53 public ObjectId Id { get; set; }
54 public string Title { get; set; }
55 public double Score { get; set; }
56}
{ "title" : "Prancer", "score" : 1.0 }
{ "title" : "Prancer Returns", "score" : 1.0 }
{ "title" : "Prince", "score" : 1.0 }
{ "title" : "Prince Avalanche", "score" : 1.0 }
{ "title" : "Prince of Broadway", "score" : 1.0 }

Atlas Search 结果包含电影片名以 PrancePrince 开头的文档。Atlas Search 返回片名为 Prance 后跟Prince 的电影,因为 Atlas Search 按title 字段升序对文档进行排序。

此代码示例将执行以下任务:

  • 导入mongodb包和依赖项。

  • 建立与您的 Atlas 集群的连接。

  • 遍历游标以打印与查询匹配的文档。

1package main
2
3import (
4 "context"
5 "fmt"
6
7 "go.mongodb.org/mongo-driver/v2/bson"
8 "go.mongodb.org/mongo-driver/v2/mongo"
9 "go.mongodb.org/mongo-driver/v2/mongo/options"
10)
11
12func main() {
13 // connect to your Atlas cluster
14 client, err := mongo.Connect(options.Client().ApplyURI("<connection-string>"))
15 if err != nil {
16 panic(err)
17 }
18 defer client.Disconnect(context.TODO())
19
20 // set namespace
21 collection := client.Database("sample_mflix").Collection("movies")
22
23 // define pipeline stages
24 searchStage := bson.D{{Key: "$search", Value: bson.M{
25 "index": "default",
26 "compound": bson.M{
27 "should": bson.A{
28 bson.M{
29 "wildcard": bson.D{
30 {Key: "path", Value: "title"},
31 {Key: "query", Value: "Prance*"},
32 {Key: "allowAnalyzedField", Value: true},
33 }},
34 bson.M{
35 "wildcard": bson.D{
36 {Key: "path", Value: "title"},
37 {Key: "query", Value: "Prince*"},
38 {Key: "allowAnalyzedField", Value: true},
39 }},
40 },
41 },
42 "sort": bson.D{{Key: "title", Value: 1}},
43 }}}
44
45 limitStage := bson.D{{Key: "$limit", Value: 5}}
46 projectStage := bson.D{{Key: "$project", Value: bson.D{{Key: "title", Value: 1}, {Key: "_id", Value: 0}, {Key: "score", Value: bson.D{{Key: "$meta", Value: "searchScore"}}}}}}
47
48 // run pipeline
49 cursor, err := collection.Aggregate(context.TODO(), mongo.Pipeline{searchStage, limitStage, projectStage})
50 if err != nil {
51 panic(err)
52 }
53
54 // print results
55 var results []bson.D
56 if err = cursor.All(context.TODO(), &results); err != nil {
57 panic(err)
58 }
59 for _, result := range results {
60 fmt.Println(result)
61 }
62}
[{title Prancer} {score 1}]
[{title Prancer Returns} {score 1}]
[{title Prince} {score 1}]
[{title Prince Avalanche} {score 1}]
[{title Prince of Broadway} {score 1}]

Atlas Search 结果包含电影片名以 PrancePrince 开头的文档。Atlas Search 返回片名为 Prance 后跟Prince 的电影,因为 Atlas Search 按title 字段升序对文档进行排序。

此代码示例将执行以下任务:

  • 导入mongodb包和依赖项。

  • 建立与您的 Atlas 集群的连接。

  • 遍历游标以打印与查询匹配的文档。

1import java.util.Arrays;
2import java.util.List;
3
4import static com.mongodb.client.model.Aggregates.limit;
5import static com.mongodb.client.model.Aggregates.project;
6import static com.mongodb.client.model.Projections.*;
7import com.mongodb.client.MongoClient;
8import com.mongodb.client.MongoClients;
9import com.mongodb.client.MongoCollection;
10import com.mongodb.client.MongoDatabase;
11import org.bson.Document;
12
13import java.util.Date;
14
15public class SortByString {
16 public static void main( String[] args ) {
17 // define clause
18 List<Document> shouldClause =
19 List.of(
20 new Document(
21 "wildcard",
22 new Document("query", "Prance*")
23 .append("path", "title")
24 .append("allowAnalyzedField", true)),
25 new Document(
26 "wildcard",
27 new Document("query", "Prince*")
28 .append("path", "title")
29 .append("allowAnalyzedField", true)));
30
31 // define query
32 Document agg =
33 new Document(
34 "$search",
35 new Document("index", "default")
36 .append("compound",
37 new Document("should", shouldClause))
38 .append("sort", new Document("title", 1L)));
39
40 // specify connection
41 String uri = "<connection-string>";
42
43 // establish connection and set namespace
44 try (MongoClient mongoClient = MongoClients.create(uri)) {
45 MongoDatabase database = mongoClient.getDatabase("sample_mflix");
46 MongoCollection<Document> collection = database.getCollection("movies");
47
48 // run query and print results
49 collection.aggregate(Arrays.asList(agg,
50 limit(5),
51 project(fields(excludeId(), include("title"), computed("score", new Document("$meta", "searchScore"))))))
52 .forEach(doc -> System.out.println(doc.toJson()));
53 }
54 }
55}
{"title": "Prancer", "score": 1.0}
{"title": "Prancer Returns", "score": 1.0}
{"title": "Prince", "score": 1.0}
{"title": "Prince Avalanche", "score": 1.0}
{"title": "Prince of Broadway", "score": 1.0}

Atlas Search 结果包含电影片名以 PrancePrince 开头的文档。Atlas Search 返回片名为 Prance 后跟Prince 的电影,因为 Atlas Search 按title 字段升序对文档进行排序。

此代码示例将执行以下任务:

  • 导入mongodb包和依赖项。

  • 建立与您的 Atlas 集群的连接。

  • 打印与 AggregateFlow 实例中的查询相匹配的文档。

1import com.mongodb.client.model.Aggregates.limit
2import com.mongodb.client.model.Aggregates.project
3import com.mongodb.client.model.Projections.*
4import com.mongodb.kotlin.client.coroutine.MongoClient
5import kotlinx.coroutines.runBlocking
6import org.bson.Document
7
8fun main() {
9 // establish connection and set namespace
10 val uri = "<connection-string>"
11 val mongoClient = MongoClient.create(uri)
12 val database = mongoClient.getDatabase("sample_mflix")
13 val collection = database.getCollection<Document>("movies")
14
15 runBlocking {
16 // define clause
17 val shouldClause = listOf(
18 Document("wildcard", Document("query", "Prance*")
19 .append("path", "title")
20 .append("allowAnalyzedField", true)),
21 Document("wildcard", Document("query", "Prince*")
22 .append("path", "title")
23 .append("allowAnalyzedField", true))
24 )
25
26 // define query
27 val agg = Document(
28 "\$search",
29 Document("index", "default")
30 .append(
31 "compound",
32 Document("should", shouldClause)
33 )
34 .append("sort", Document("title", 1L))
35 )
36
37 // run query and print results
38 val resultsFlow = collection.aggregate<Document>(
39 listOf(
40 agg,
41 limit(5),
42 project(fields(
43 excludeId(),
44 include("title"),
45 computed("score", Document("\$meta", "searchScore"))
46 ))
47 )
48 )
49 resultsFlow.collect { println(it) }
50 }
51 mongoClient.close()
52}
Document{{title=Prancer, score=1.0}}
Document{{title=Prancer Returns, score=1.0}}
Document{{title=Prince, score=1.0}}
Document{{title=Prince Avalanche, score=1.0}}
Document{{title=Prince of Broadway, score=1.0}}

Atlas Search 结果包含电影片名以 PrancePrince 开头的文档。Atlas Search 返回片名为 Prance 后跟Prince 的电影,因为 Atlas Search 按title 字段升序对文档进行排序。

此代码示例将执行以下任务:

  • 导入 mongodb,即 MongoDB 的 Node.js 驱动程序。

  • 创建一个 MongoClient 类实例,以建立与 Atlas 集群的连接。

  • 查询使用了下列管道阶段:

    • $search 使用带有通配符操作符的 should 子句搜索 title 字段,搜索以 PrancePrince 开头的名称。该查询还指定结果必须按 title 字段升序排序。

    • $limit 阶段将输出限制为 5 个结果。

    • $project 阶段到:

      • 排除 title 以外的所有字段。

      • 添加名为 score 的字段。

  • 遍历游标以打印与查询匹配的文档。

1const { MongoClient } = require("mongodb");
2
3// Replace the uri string with your MongoDB deployments connection string.
4const uri =
5 "<connection-string>";
6
7const client = new MongoClient(uri);
8
9async function run() {
10 try {
11 await client.connect();
12
13 // set namespace
14 const database = client.db("sample_mflix");
15 const coll = database.collection("movies");
16
17 // define pipeline
18 const agg = [
19 {
20 '$search': {
21 'compound': {
22 'should': [
23 {
24 'wildcard': {
25 'query': [
26 'Prance*'
27 ],
28 'path': 'title',
29 'allowAnalyzedField': true
30 }
31 }, {
32 'wildcard': {
33 'query': [
34 'Prince*'
35 ],
36 'path': 'title',
37 'allowAnalyzedField': true
38 }
39 }
40 ]
41 },
42 'sort': { 'title': 1 }
43 }
44 }, {
45 '$limit': 5
46 }, {
47 '$project': {'_id': 0, 'title': 1, 'score': {'$meta': 'searchScore'}
48 }
49 }
50 ];
51
52 // run pipeline
53 const result = await coll.aggregate(agg);
54
55 // print results
56 await result.forEach((doc) => console.log(doc));
57
58 } finally {
59 await client.close();
60 }
61}
62run().catch(console.dir);
{ title: 'Prancer', score: 1 }
{ title: 'Prancer Returns', score: 1 }
{ title: 'Prince', score: 1 }
{ title: 'Prince Avalanche', score: 1 }
{ title: 'Prince of Broadway', score: 1 }

Atlas Search 结果包含电影片名以 PrancePrince 开头的文档。Atlas Search 返回片名为 Prance 后跟Prince 的电影,因为 Atlas Search 按title 字段升序对文档进行排序。

以下代码示例:

  • 导入 pymongo 、MongoDB 的 Python 驱动程序和 dns 模块,这是使用 DNS 种子列表连接字符串将 pymongo 连接到 Atlas 所必需的。

  • 创建一个 MongoClient 类实例,以建立与 Atlas 集群的连接。

  • 查询使用了下列管道阶段:

    • $search 使用带有通配符操作符的 should 子句搜索 title 字段,搜索以 PrancePrince 开头的名称。该查询还指定结果必须按 title 字段升序排序。

    • $limit 阶段将输出限制为 5 个结果。

    • $project 阶段到:

      • 排除 title 以外的所有字段。

      • 添加名为 score 的字段。

  • 遍历游标以打印与查询匹配的文档。

1import pymongo
2
3# connect to your Atlas cluster
4client = pymongo.MongoClient('<connection-string>')
5
6# define pipeline
7pipeline = [
8 {'$search': {
9 'compound': {
10 'should': [{'wildcard': {'query': 'Prance*', 'path': 'title', 'allowAnalyzedField': True}},
11 {'wildcard': {'query': 'Prince*', 'path': 'title', 'allowAnalyzedField': True}}]
12 },
13 'sort': { 'title': 1 }}},
14 {'$limit': 5},
15 {'$project': {'_id': 0, 'title': 1, 'score': {'$meta': 'searchScore'}}}
16]
17
18# run pipeline
19result = client['sample_mflix']['movies'].aggregate(pipeline)
20
21# print results
22for i in result:
23 print(i)
{'title': 'Prancer', 'score': 1.0}
{'title': 'Prancer Returns', 'score': 1.0}
{'title': 'Prince', 'score': 1.0}
{'title': 'Prince Avalanche', 'score': 1.0}
{'title': 'Prince of Broadway', 'score': 1.0}

Atlas Search 结果包含电影片名以 PrancePrince 开头的文档。Atlas Search 返回片名为 Prance 后跟Prince 的电影,因为 Atlas Search 按title 字段升序对文档进行排序。

以下查询显示了如何在不区分字母大小写的情况下对结果进行排序。它使用文本操作符搜索 title 字段中包含术语 train 的电影,然后按 title 字段值升序对结果进行排序。

该查询指定了一个$limit阶段以将结果中的文档限制为5 ,还指定了一个$project阶段来执行以下操作:

  • 仅在结果中包含_idtitleawards字段。

  • 在结果中添加名为 score 的字段。

[
{
"$search": {
"text": {
"path": "title",
"query": "train",
},
"sort": {
"title": 1
}
}
}
]
SCORE: 3.317898988723755 _id: "573a139cf29313caabcf662c"
plot: "A train filled with atomic devices threatens to destroy the city of De…"
genres: Array
runtime: 122
SCORE: 3.317898988723755 _id: "64de50ae2932de4dd3203061"
genres: Array
title: "atomic train"
awards: Object
SCORE: 2.228306293487549 _id: "573a13bbf29313caabd52ff4"
fullplot: "Long ago up North on the Island of Berk, the young Viking, Hiccup, wan…"
imdb: Object
year: 2010
SCORE: 2.228306293487549 _id: "64de50da2932de4dd3204393"
genres: Array
title: "how to train your dragon"
awards: Object
SCORE: 2.008449077606201 _id: "573a13ccf29313caabd83281"
plot: "When Hiccup and Toothless discover an ice cave that is home to hundred…"
genres: Array
runtime: 102
SCORE: 1.4400973320007324 _id: "573a13b1f29313caabd36490"
plot: "The life and times of Howard Zinn: the historian, activist, and author…"
genres: Array
runtime: 78
SCORE: 2.228306293487549 _id: "573a1394f29313caabce0fb4"
plot: "A marshal tries to bring the son of an old friend, an autocratic cattl…"
genres: Array
runtime: 95
SCORE: 2.8528976440429688 _id: "573a13c8f29313caabd78a6b"
plot: "A couple embarks on a journey home for Chinese new year along with 130…"
genres: Array
runtime: 85
SCORE: 2.502213716506958 _id: "573a13baf29313caabd50811"
plot: "Two thugs from the Perth suburb of Midland catch the last train to Fre…"
genres: Array
runtime: 89
SCORE: 2.502213716506958 _id: "573a13a7f29313caabd1b667"
fullplot: "A teacher and a gangster meet by chance in a small town pharmacy. As a…"
imdb: Object
year: 2002

结果包含已排序的文档,无论字母大小写如何。 但是,如果将normalizer设置为none ,Atlas Search 将返回以下结果:

SCORE: 3.317898988723755 _id: "573a139cf29313caabcf662c"
plot: "A train filled with atomic devices threatens to destroy the city of De…"
genres: Array
runtime: 122
SCORE: 2.2382168769836426 _id: "573a13bbf29313caabd52ff4"
fullplot: "Long ago up North on the Island of Berk, the young Viking, Hiccup, wan…"
imdb: object
year: 2010
SCORE: 2.008449077606201 _id: "573a13ccf29313caabd83281"
plot: "When Hiccup and Toothless discover an ice cave that is home to hundred…"
genres: Array
runtime: 102
SCORE: 1.4400973320007324 _id: "573a13b1f29313caabd36490"
plot: "The life and times of Howard Zinn: the historian, activist, and author…"
genres: Array
runtime: 78
SCORE: 2.8528976440429688 _id: "573a13c8f29313caabd78a6b"
plot: "A couple embarks on a journey home for Chinese new year along with 130…"
genres: Array
runtime: 85
SCORE: 2.228306293487549 _id: "573a1394f29313caabce0fb4"
plot: "A marshal tries to bring the son of an old friend, an autocratic cattl…"
genres: Array
runtime: 95
SCORE: 2.502213716506958 _id: "573a13baf29313caabd50811"
plot: "Two thugs from the Perth suburb of Midland catch the last train to Fre…"
genres: Array
runtime: 89
SCORE: 2.502213716506958 _id: "573a13a7f29313caabd1b667"
fullplot: "A teacher and a gangster meet by chance in a small town pharmacy. As a…"
imdb: Object
year: 2002
SCORE: 3.3326687812805176 _id: "573a139af29313caabcef573"
plot: "A vengeful New York transit cop decides to steal a trainload of subway…"
genres: Array
runtime: 110
SCORE: 3.3326687812805176 _id: "573a1398f29313caabceb8f2"
plot: "Three stories are connected by a Memphis hotel and the spirit of Elvis…"
genres: Array
runtime: 110

要在不规范化字母大小写的情况下对结果进行排序,请在索引定义中将 normalizer 选项设置为 none(第 7 行),保存索引定义,然后重新查询。

db.movies.aggregate(
{
"$search": {
"index": "default",
"text": {
"path": "title",
"query": "train",
},
"sort": {
"title": 1
}
}
},
{
"$limit": 5
},
{
"$project": {
"_id": 1,
"title": 1,
"awards": 1,
"score": { $meta: "searchScore" }
}
}
)
[
{
_id: ObjectId("573a139cf29313caabcf662c"),
title: 'Atomic Train',
awards: { wins: 1, nominations: 1, text: '1 win & 1 nomination.' },
score: 3.317898988723755
},
{
_id: ObjectId("64de50ae2932de4dd3203061"),
title: 'atomic train',
awards: { wins: 1, nominations: 1 },
score: 3.317898988723755
},
{
_id: ObjectId("573a13bbf29313caabd52ff4"),
title: 'How to Train Your Dragon',
awards: {
wins: 32,
nominations: 51,
text: 'Nominated for 2 Oscars. Another 30 wins & 51 nominations.'
},
score: 2.228306293487549
},
{
_id: ObjectId("64de50da2932de4dd3204393"),
title: 'how to train your dragon',
awards: { wins: 32, nominations: 51 },
score: 2.228306293487549
},
{
_id: ObjectId("573a13ccf29313caabd83281"),
title: 'How to Train Your Dragon 2',
awards: {
wins: 18,
nominations: 52,
text: 'Nominated for 1 Oscar. Another 17 wins & 52 nominations.'
},
score: 2.008449077606201
}
]

结果包含已排序的文档,无论字母大小写如何。 但是,如果将normalizer设置为none ,Atlas Search 将返回以下结果:

[
{
_id: ObjectId("573a139cf29313caabcf662c"),
title: 'Atomic Train',
awards: { wins: 1, nominations: 1, text: '1 win & 1 nomination.' },
score: 3.3326687812805176
},
{
_id: ObjectId("573a13bbf29313caabd52ff4"),
title: 'How to Train Your Dragon',
awards: {
wins: 32,
nominations: 51,
text: 'Nominated for 2 Oscars. Another 30 wins & 51 nominations.'
},
score: 2.2382168769836426
},
{
_id: ObjectId("573a13ccf29313caabd83281"),
title: 'How to Train Your Dragon 2',
awards: {
wins: 18,
nominations: 52,
text: 'Nominated for 1 Oscar. Another 17 wins & 52 nominations.'
},
score: 2.0173802375793457
},
{
_id: ObjectId("573a13b1f29313caabd36490"),
title: "Howard Zinn: You Can't Be Neutral on a Moving Train",
awards: { wins: 1, nominations: 0, text: '1 win.' },
score: 1.446497917175293
},
{
_id: ObjectId("573a13c8f29313caabd78a6b"),
title: 'Last Train Home',
awards: { wins: 14, nominations: 9, text: '14 wins & 9 nominations.' },
score: 2.8655927181243896
}
]

要在不规范化字母大小写的情况下对结果进行排序,请在索引定义中将 normalizer 选项设置为 none(第 7 行),保存索引定义,然后重新查询。

管道阶段
查询

$search

{
"index": "default",
"text": {
"path": "title",
"query": "train",
},
"sort": {
"title": 1,
}
}

$limit

5

$project

{
"_id": 1,
"title": 1,
"awards": 1,
"score": { $meta: "searchScore" }
}

如果已启用 Auto Preview,则 MongoDB Compass 将在 $project 管道阶段旁边显示以下文档:

_id: ObjectId('573a139cf29313caabcf662c')
title: 'Atomic Train'
awards: Object
score: 3.317898988723755
_id: ObjectId("64de50ae2932de4dd3203061")
title: 'atomic train'
awards: Object
score: 3.317898988723755
_id: ObjectId('573a13bbf29313caabd52ff4')
title: 'How to Train Your Dragon'
awards: Object
score: 2.228306293487549
_id: ObjectId("64de50da2932de4dd3204393"),
title: 'how to train your dragon'
awards:
score: 2.228306293487549
_id: ObjectId('573a13ccf29313caabd83281')
title: 'How to Train Your Dragon 2'
awards: object
score: 2.0173802375793457

结果包含已排序的文档,无论字母大小写如何。 但是,如果将normalizer设置为none ,Atlas Search 将返回以下结果:

1using MongoDB.Bson;
2using MongoDB.Bson.Serialization.Attributes;
3using MongoDB.Bson.Serialization.Conventions;
4using MongoDB.Driver;
5using MongoDB.Driver.Search;
6
7public class CaseInsensitiveSort
8{
9 private const string MongoConnectionString = "<connection-string>";
10
11 public static void Main(string[] args)
12 {
13 // allow automapping of the camelCase database fields to our MovieDocument
14 var camelCaseConvention = new ConventionPack { new camelCaseConvention() };
15 ConventionRegistry.Register("CamelCase", camelCaseConvention, type => true);
16
17 // connect to your Atlas cluster
18 var mongoClient = new MongoClient(MongoConnectionString);
19 var yourDatabase = mongoClient.GetDatabase("sample_mflix");
20 var moviesCollection = yourDatabase.GetCollection<MovieDocument>("movies");
21
22 // define options for search
23 var searchOptions = new SearchOptions<MovieDocument>() {
24 Sort = Builders<MovieDocument>.Sort.Ascending(movie => movie.Title),
25 IndexName = "default"
26 };
27
28 // define and run pipeline
29 var results = moviesCollection.Aggregate()
30 .Search(Builders<MovieDocument>.Search.Text(movie => movie.Title, "train"), searchOptions)
31 .Limit (5)
32 .Project<MovieDocument>(Builders<MovieDocument>.Projection
33 .Include(movie => movie.Id)
34 .Include(movie => movie.Title)
35 .Include(movie => movie.Awards)
36 .MetaSearchScore(movie => movie.Score))
37 .ToList();
38
39 // print results
40 foreach (var movie in results)
41 {
42 Console.WriteLine(movie.ToJson());
43 }
44 }
45}
46
47[BsonIgnoreExtraElements]
48public class MovieDocument
49{
50 [BsonIgnoreIfDefault]
51 public ObjectId Id { get; set; }
52 public string Title { get; set; }
53 public Award Awards { get; set; }
54 public double Score { get; set; }
55}
56
57[BsonIgnoreExtraElements]
58public class Award
59{
60 public int Wins { get; set; }
61 public int Nominations { get; set; }
62}
{ "_id" : ObjectId("573a139cf29313caabcf662c"), "title" : "Atomic Train", "awards" : { "wins" : 1, "nominations" : 1 }, "score" : 3.3035578727722168 }
{ "_id" : ObjectId("64de50ae2932de4dd3203061"), "title" : "atomic train", "awards" : { "wins" : 1, "nominations" : 1 }, "score" : 3.3035578727722168 }
{ "_id" : ObjectId("573a13bbf29313caabd52ff4"), "title" : "How to Train Your Dragon", "awards" : { "wins" : 32, "nominations" : 51 }, "score" : 2.2186923027038574 }
{ "_id" : ObjectId("64de50da2932de4dd3204393"), "title" : "how to train your dragon", "awards" : { "wins" : 32, "nominations" : 51 }, "score" : 2.2186923027038574 }
{ "_id" : ObjectId("573a13ccf29313caabd83281"), "title" : "How to Train Your Dragon 2", "awards" : { "wins" : 18, "nominations" : 52 }, "score" : 1.9997868537902832 }

结果包含已排序的文档,无论字母大小写如何。 但是,如果将normalizer设置为none ,Atlas Search 将返回以下结果:

{ "_id" : ObjectId("573a139cf29313caabcf662c"), "title" : "Atomic Train", "awards" : { "wins" : 1, "nominations" : 1 }, "score" : 3.3035225868225098 }
{ "_id" : ObjectId("573a13bbf29313caabd52ff4"), "title" : "How to Train Your Dragon", "awards" : { "wins" : 32, "nominations" : 51 }, "score" : 2.2186522483825684 }
{ "_id" : ObjectId("573a13ccf29313caabd83281"), "title" : "How to Train Your Dragon 2", "awards" : { "wins" : 18, "nominations" : 52 }, "score" : 1.9997482299804688 }
{ "_id" : ObjectId("573a13b1f29313caabd36490"), "title" : "Howard Zinn: You Can't Be Neutral on a Moving Train", "awards" : { "wins" : 1, "nominations" : 0 }, "score" : 1.4338588714599609 }
{ "_id" : ObjectId("573a13c8f29313caabd78a6b"), "title" : "Last Train Home", "awards" : { "wins" : 14, "nominations" : 9 }, "score" : 2.8405368328094482 }

要在不规范化字母大小写的情况下对结果进行排序,请在索引定义中将 normalizer 选项设置为 none(第 7 行),保存索引定义,然后重新查询。

1package main
2
3import (
4 "context"
5 "fmt"
6
7 "go.mongodb.org/mongo-driver/bson"
8 "go.mongodb.org/mongo-driver/mongo"
9 "go.mongodb.org/mongo-driver/mongo/options"
10)
11
12func main() {
13 // connect to your Atlas cluster
14 client, err := mongo.Connect(context.TODO(), options.Client().ApplyURI("<connection-string>"))
15 if err != nil {
16 panic(err)
17 }
18 defer client.Disconnect(context.TODO())
19
20 // set namespace
21 collection := client.Database("sample_mflix").Collection("movies")
22
23 // define pipeline stages
24 searchStage := bson.D{{"$search", bson.M{
25 "index": "default",
26 "text": bson.D{
27 {"path", "title"},
28 {"query", "train"},
29 },
30 "sort": bson.D{{"title", 1}},
31 }}}
32 limitStage := bson.D{{"$limit", 5}}
33 projectStage := bson.D{{"$project", bson.D{{"_id", 1}, {"title", 1}, {"awards", 1}, {"score", bson.D{{"$meta", "searchScore"}}}}}}
34
35 // run pipeline
36 cursor, err := collection.Aggregate(context.TODO(), mongo.Pipeline{searchStage, limitStage, projectStage})
37 if err != nil {
38 panic(err)
39 }
40
41 // print results
42 var results []bson.D
43 if err = cursor.All(context.TODO(), &results); err != nil {
44 panic(err)
45 }
46 for _, result := range results {
47 fmt.Println(result)
48 }
49}
[{_id ObjectID("573a139cf29313caabcf662c")} {title Atomic Train} {awards [{wins 1} {nominations 1} {text 1 win & 1 nomination.}]} {score 3.317898988723755}]
[{_id ObjectId("64de50ae2932de4dd3203061")} {title atomic train} {awards [{wins 1} {nominations 1}]} {score 3.317898988723755}]
[{_id ObjectID("573a13bbf29313caabd52ff4")} {title How to Train Your Dragon} {awards [{wins 32} {nominations 51} {text Nominated for 2 Oscars. Another 30 wins & 51 nominations.}]} {score 2.228306293487549}]
[{_id ObjectId("64de50da2932de4dd3204393")} {title how to train your dragon} {awards [{wins 32} {nominations 51}]} {score 2.228306293487549}]
[{_id ObjectID("573a13ccf29313caabd83281")} {title How to Train Your Dragon 2} {awards [{wins 18} {nominations 52} {text Nominated for 1 Oscar. Another 17 wins & 52 nominations.}]} {score 2.008449077606201}]

结果包含已排序的文档,无论字母大小写如何。 但是,如果将normalizer设置为none ,Atlas Search 将返回以下结果:

[{_id ObjectID("573a139cf29313caabcf662c")} {title Atomic Train} {awards [{wins 1} {nominations 1} {text 1 win & 1 nomination.}]} {score 3.3326687812805176}]
[{_id ObjectID("573a13bbf29313caabd52ff4")} {title How to Train Your Dragon} {awards [{wins 32} {nominations 51} {text Nominated for 2 Oscars. Another 30 wins & 51 nominations.}]} {score 2.2382168769836426}]
[{_id ObjectID("573a13ccf29313caabd83281")} {title How to Train Your Dragon 2} {awards [{wins 18} {nominations 52} {text Nominated for 1 Oscar. Another 17 wins & 52 nominations.}]} {score 2.0173802375793457}]
[{_id ObjectID("573a13b1f29313caabd36490")} {title Howard Zinn: You Can't Be Neutral on a Moving Train} {awards [{wins 1} {nominations 0} {text 1 win.}]} {score 1.446497917175293}]
[{_id ObjectID("573a13c8f29313caabd78a6b")} {title Last Train Home} {awards [{wins 14} {nominations 9} {text 14 wins & 9 nominations.}]} {score 2.8655927181243896}]

要在不规范化字母大小写的情况下对结果进行排序,请在索引定义中将 normalizer 选项设置为 none(第 7 行),保存索引定义,然后重新查询。

1import java.util.Arrays;
2import static com.mongodb.client.model.Aggregates.limit;
3import static com.mongodb.client.model.Aggregates.project;
4import static com.mongodb.client.model.Projections.*;
5import com.mongodb.client.MongoClient;
6import com.mongodb.client.MongoClients;
7import com.mongodb.client.MongoCollection;
8import com.mongodb.client.MongoDatabase;
9import org.bson.Document;
10
11public class CaseInsensitiveQuery {
12 public static void main( String[] args ) {
13 // define query
14 Document agg =
15 new Document("$search",
16 new Document("index", "default")
17 .append("text",
18 new Document("path", "title")
19 .append("query", "train"))
20 .append("sort",
21 new Document("title", 1)));
22
23 // specify connection
24 String uri = "<connection-string>";
25
26 // establish connection and set namespace
27 try (MongoClient mongoClient = MongoClients.create(uri)) {
28 MongoDatabase database = mongoClient.getDatabase("sample_mflix");
29 MongoCollection<Document> collection = database.getCollection("movies");
30
31 // run query and print results
32 collection.aggregate(Arrays.asList(agg,
33 limit(5),
34 project(fields(include("_id"), include("title"), include("awards"), computed("score", new Document("$meta", "searchScore"))))))
35 .forEach(doc -> System.out.println(doc.toJson()));
36 }
37 }
38}
{"_id": {"$oid": "573a139cf29313caabcf662c"}, "title": "Atomic Train", "awards": {"wins": 1, "nominations": 1, "text": "1 win & 1 nomination."}, "score": 3.317898988723755}
{"_id": {"$oid": "64de50ae2932de4dd3203061"}, "title": "atomic train", "awards": {"wins": 1, "nominations": 1}, "score": 3.317898988723755}
{"_id": {"$oid": "573a13bbf29313caabd52ff4"}, "title": "How to Train Your Dragon", "awards": {"wins": 32, "nominations": 51, "text": "Nominated for 2 Oscars. Another 30 wins & 51 nominations."}, "score": 2.228306293487549}
{"_id": {"$oid": "64de50da2932de4dd3204393"}, "title": "how to train your dragon", "awards": {"wins": 32, "nominations": 51}, "score": 2.228306293487549}
{"_id": {"$oid": "573a13ccf29313caabd83281"}, "title": "How to Train Your Dragon 2", "awards": {"wins": 18, "nominations": 52, "text": "Nominated for 1 Oscar. Another 17 wins & 52 nominations."}, "score": 2.008449077606201}

结果包含已排序的文档,无论字母大小写如何。 但是,如果将normalizer设置为none ,Atlas Search 将返回以下结果:

{"_id": {"$oid": "573a139cf29313caabcf662c"}, "title": "Atomic Train", "awards": {"wins": 1, "nominations": 1, "text": "1 win & 1 nomination."}, "score": 3.3326687812805176}
{"_id": {"$oid": "573a13bbf29313caabd52ff4"}, "title": "How to Train Your Dragon", "awards": {"wins": 32, "nominations": 51, "text": "Nominated for 2 Oscars. Another 30 wins & 51 nominations."}, "score": 2.2382168769836426}
{"_id": {"$oid": "573a13ccf29313caabd83281"}, "title": "How to Train Your Dragon 2", "awards": {"wins": 18, "nominations": 52, "text": "Nominated for 1 Oscar. Another 17 wins & 52 nominations."}, "score": 2.0173802375793457}
{"_id": {"$oid": "573a13b1f29313caabd36490"}, "title": "Howard Zinn: You Can't Be Neutral on a Moving Train", "awards": {"wins": 1, "nominations": 0, "text": "1 win."}, "score": 1.446497917175293}
{"_id": {"$oid": "573a13c8f29313caabd78a6b"}, "title": "Last Train Home", "awards": {"wins": 14, "nominations": 9, "text": "14 wins & 9 nominations."}, "score": 2.8655927181243896}

要在不规范化字母大小写的情况下对结果进行排序,请在索引定义中将 normalizer 选项设置为 none(第 7 行),保存索引定义,然后重新查询。

1import com.mongodb.client.model.Aggregates.limit
2import com.mongodb.client.model.Aggregates.project
3import com.mongodb.client.model.Projections.*
4import com.mongodb.kotlin.client.coroutine.MongoClient
5import kotlinx.coroutines.runBlocking
6import org.bson.Document
7
8fun main() {
9 // establish connection and set namespace
10 val uri = "<connection-string>"
11 val mongoClient = MongoClient.create(uri)
12 val database = mongoClient.getDatabase("sample_mflix")
13 val collection = database.getCollection<Document>("movies")
14
15 runBlocking {
16 // define query
17 val agg = Document(
18 "\$search",
19 Document("index", "default")
20 .append(
21 "text",
22 Document("path", "title")
23 .append("query", "train")
24 )
25 .append(
26 "sort",
27 Document("title", 1)
28 )
29 )
30
31 // run query and print results
32 val resultsFlow = collection.aggregate<Document>(
33 listOf(
34 agg,
35 limit(5),
36 project(fields(
37 excludeId(),
38 include("title", "awards"),
39 computed("score", Document("\$meta", "searchScore"))
40 ))
41 )
42 )
43 resultsFlow.collect { println(it) }
44 }
45 mongoClient.close()
46}
Document{{title=atomic train, awards=Document{{wins=1, nominations=1}}, score=3.3326687812805176}}
Document{{title=Atomic Train, awards=Document{{wins=1, nominations=1, text=1 win & 1 nomination.}}, score=3.3326687812805176}}
Document{{title=how to train your dragon, awards=Document{{wins=32, nominations=51}}, score=2.2382168769836426}}
Document{{title=How to Train Your Dragon, awards=Document{{wins=32, nominations=51, text=Nominated for 2 Oscars. Another 30 wins & 51 nominations.}}, score=2.2382168769836426}}
Document{{title=How to Train Your Dragon 2, awards=Document{{wins=18, nominations=52, text=Nominated for 1 Oscar. Another 17 wins & 52 nominations.}}, score=2.0173802375793457}}

结果包含已排序的文档,无论字母大小写如何。 但是,如果将normalizer设置为none ,Atlas Search 将返回以下结果:

Document{{title=Atomic Train, awards=Document{{wins=1, nominations=1, text=1 win & 1 nomination.}}, score=3.3326687812805176}}
Document{{title=How to Train Your Dragon, awards=Document{{wins=32, nominations=51, text=Nominated for 2 Oscars. Another 30 wins & 51 nominations.}}, score=2.2382168769836426}}
Document{{title=How to Train Your Dragon 2, awards=Document{{wins=18, nominations=52, text=Nominated for 1 Oscar. Another 17 wins & 52 nominations.}}, score=2.0173802375793457}}
Document{{title=Howard Zinn: You Can't Be Neutral on a Moving Train, awards=Document{{wins=1, nominations=0, text=1 win.}}, score=1.446497917175293}}
Document{{title=Last Train Home, awards=Document{{wins=14, nominations=9, text=14 wins & 9 nominations.}}, score=2.8655927181243896}}

要在不规范化字母大小写的情况下对结果进行排序,请在索引定义中将 normalizer 选项设置为 none(第 7 行),保存索引定义,然后重新查询。

1const { MongoClient } = require("mongodb");
2
3// Replace the uri string with your MongoDB deployments connection string.
4const uri =
5 "<connection-string>";
6
7const client = new MongoClient(uri);
8
9async function run() {
10 try {
11 await client.connect();
12
13 // set namespace
14 const database = client.db("sample_mflix");
15 const coll = database.collection("movies");
16
17 // define pipeline
18 const agg = [
19 {
20 '$search': {
21 'index': 'default',
22 'text': { 'path': 'title', 'query': 'train' },
23 'sort': { 'title': 1 }
24 }
25 }, {
26 '$limit': 5
27 }, {
28 '$project': { '_id': 1, 'title': 1, 'awards': 1, 'score': { '$meta': 'searchScore' }}
29 }
30 ];
31
32 // run pipeline
33 const result = await coll.aggregate(agg);
34
35 // print results
36 await result.forEach((doc) => console.log(doc));
37
38 } finally {
39 await client.close();
40 }
41}
42run().catch(console.dir);
{
_id: new ObjectId("573a139cf29313caabcf662c"),
title: 'Atomic Train',
awards: { wins: 1, nominations: 1, text: '1 win & 1 nomination.' },
score: 3.317898988723755
}
{
_id: new ObjectId("64de50ae2932de4dd3203061"),
title: 'atomic train',
awards: { wins: 1, nominations: 1 },
score: 3.317898988723755
}
{
_id: new ObjectId("573a13bbf29313caabd52ff4"),
title: 'How to Train Your Dragon',
awards: {
wins: 32,
nominations: 51,
text: 'Nominated for 2 Oscars. Another 30 wins & 51 nominations.'
},
score: 2.228306293487549
}
{
_id: new ObjectId("64de50da2932de4dd3204393"),
title: 'how to train your dragon',
awards: { wins: 32, nominations: 51 },
score: 2.228306293487549
}
{
_id: new ObjectId("573a13ccf29313caabd83281"),
title: 'How to Train Your Dragon 2',
awards: {
wins: 18,
nominations: 52,
text: 'Nominated for 1 Oscar. Another 17 wins & 52 nominations.'
},
score: 2.008449077606201
}

结果包含已排序的文档,无论字母大小写如何。 但是,如果将normalizer设置为none ,Atlas Search 将返回以下结果:

{
_id: new ObjectId("573a139cf29313caabcf662c"),
title: 'Atomic Train',
awards: { wins: 1, nominations: 1, text: '1 win & 1 nomination.' },
score: 3.3326687812805176
}
{
_id: new ObjectId("573a13bbf29313caabd52ff4"),
title: 'How to Train Your Dragon',
awards: {
wins: 32,
nominations: 51,
text: 'Nominated for 2 Oscars. Another 30 wins & 51 nominations.'
},
score: 2.2382168769836426
}
{
_id: new ObjectId("573a13ccf29313caabd83281"),
title: 'How to Train Your Dragon 2',
awards: {
wins: 18,
nominations: 52,
text: 'Nominated for 1 Oscar. Another 17 wins & 52 nominations.'
},
score: 2.0173802375793457
}
{
_id: new ObjectId("573a13b1f29313caabd36490"),
title: "Howard Zinn: You Can't Be Neutral on a Moving Train",
awards: { wins: 1, nominations: 0, text: '1 win.' },
score: 1.446497917175293
}
{
_id: new ObjectId("573a13c8f29313caabd78a6b"),
title: 'Last Train Home',
awards: { wins: 14, nominations: 9, text: '14 wins & 9 nominations.' },
score: 2.8655927181243896
}

要在不规范化字母大小写的情况下对结果进行排序,请在索引定义中将 normalizer 选项设置为 none(第 7 行),保存索引定义,然后重新查询。

1import pymongo
2
3# connect to your Atlas cluster
4client = pymongo.MongoClient('<connection-string>')
5
6# define pipeline
7pipeline = [
8 {
9 '$search': {
10 'index': 'default',
11 'text': { 'path': 'title', 'query': 'train' },
12 'sort': { 'title': 1 }
13 }
14 }, {
15 '$limit': 5
16 }, {
17 '$project': { '_id': 1, 'title': 1, 'awards': 1, 'score': { '$meta': 'searchScore' } }
18 }
19]
20
21# run pipeline
22result = client['sample_mflix']['movies'].aggregate(pipeline)
23
24# print results
25for i in result:
26 print(i)
{'_id': ObjectId('573a139cf29313caabcf662c'), 'title': 'Atomic Train', 'awards': {'wins': 1, 'nominations': 1, 'text': '1 win & 1 nomination.'}, 'score': 3.317898988723755}
{'_id': ObjectId('64de50ae2932de4dd3203061'), 'title': 'atomic train', 'awards': {'wins': 1, 'nominations': 1}, 'score': 3.317898988723755}
{'_id': ObjectId('573a13bbf29313caabd52ff4'), 'title': 'How to Train Your Dragon', 'awards': {'wins': 32, 'nominations': 51, 'text': 'Nominated for 2 Oscars. Another 30 wins & 51 nominations.'}, 'score': 2.228306293487549}
{'_id': ObjectId('64de50da2932de4dd3204393'), 'title': 'how to train your dragon', 'awards': {'wins': 32, 'nominations': 51}, 'score': 2.228306293487549}
{'_id': ObjectId('573a13ccf29313caabd83281'), 'title': 'How to Train Your Dragon 2', 'awards': {'wins': 18, 'nominations': 52, 'text': 'Nominated for 1 Oscar. Another 17 wins & 52 nominations.'}, 'score': 2.008449077606201}

结果包含已排序的文档,无论字母大小写如何。 但是,如果将normalizer设置为none ,Atlas Search 将返回以下结果:

{'_id': ObjectId('573a139cf29313caabcf662c'), 'title': 'Atomic Train', 'awards': {'wins': 1, 'nominations': 1, 'text': '1 win & 1 nomination.'}, 'score': 3.3326687812805176}
{'_id': ObjectId('573a13bbf29313caabd52ff4'), 'title': 'How to Train Your Dragon', 'awards': {'wins': 32, 'nominations': 51, 'text': 'Nominated for 2 Oscars. Another 30 wins & 51 nominations.'}, 'score': 2.2382168769836426}
{'_id': ObjectId('573a13ccf29313caabd83281'), 'title': 'How to Train Your Dragon 2', 'awards': {'wins': 18, 'nominations': 52, 'text': 'Nominated for 1 Oscar. Another 17 wins & 52 nominations.'}, 'score': 2.0173802375793457}
{'_id': ObjectId('573a13b1f29313caabd36490'), 'title': "Howard Zinn: You Can't Be Neutral on a Moving Train", 'awards': {'wins': 1, 'nominations': 0, 'text': '1 win.'}, 'score': 1.446497917175293}
{'_id': ObjectId('573a13c8f29313caabd78a6b'), 'title': 'Last Train Home', 'awards': {'wins': 14, 'nominations': 9, 'text': '14 wins & 9 nominations.'}, 'score': 2.8655927181243896}

要在不规范化字母大小写的情况下对结果进行排序,请在索引定义中将 normalizer 选项设置为 none(第 7 行),保存索引定义,然后重新查询。

以下查询使用范围操作符在 sample_mflix.movies 集合中的 released 字段中搜索在 2015-01-012015-12-31 之间上映的电影。它按 _id 字段对结果进行排序,该字段包含 ObjectId类型的值,按降序排列。

db.movies.aggregate([
{
"$search": {
"range": {
"path": "released",
"gt": ISODate("2015-01-01T00:00:00.000Z"),
"lt": ISODate("2015-12-31T00:00:00.000Z")
},
"sort": {
"_id": -1
}
}
},
{
"$limit": 5
},
{
"$project": {
"_id": 1,
"title": 1,
"released": 1,
"score": { "$meta": "searchScore" }
}
}
])
[
{
_id: ObjectId('573a13fbf29313caabdedf31'),
title: 'No Home Movie',
released: ISODate('2015-08-10T00:00:00.000Z'),
score: 1
},
{
_id: ObjectId('573a13fbf29313caabdedf30'),
title: 'Our Loved Ones',
released: ISODate('2015-08-12T00:00:00.000Z'),
score: 1
},
{
_id: ObjectId('573a13faf29313caabded406'),
title: 'The Red Spider',
released: ISODate('2015-11-20T00:00:00.000Z'),
score: 1
},
{
_id: ObjectId('573a13faf29313caabded1d6'),
title: 'The Laundryman',
released: ISODate('2015-07-11T00:00:00.000Z'),
score: 1
},
{
_id: ObjectId('573a13faf29313caabdecaf3'),
title: 'Right Now, Wrong Then',
released: ISODate('2015-09-01T00:00:00.000Z'),
score: 1
}
]

以下查询在 users 集合的字段 b 中搜索术语 hello。该查询按包含多态数据(以演示排序顺序)的字段 a 对结果进行升序排序。

db.users.aggregate([
{
"$search": {
"text": {
"path": "b",
"query": "hello"
},
"sort": {
"a": 1
}
}
},
{
"$project": {
"_id": 1,
"a": 1,
"score": { "$meta": "searchScore" }
}
}
])
[
{ _id: 3, score: 0.029335692524909973 },
{
_id: 0,
a: UUID('1a324de2-e34b-c87e-f2a1-42ce37ad74ed'),
score: 0.029335692524909973
},
{
_id: 1,
a: UUID('3b241101-e2bb-4255-8caf-4136c566a962'),
score: 0.029335692524909973
},
{
_id: 6,
a: UUID('7eeddf21-b313-4a5c-81c2-c68915daa618'),
score: 0.029335692524909973
},
{
_id: 4,
a: UUID('d3c12e1c-c36e-25ed-7c3e-1e7f1e53c752'),
score: 0.029335692524909973
},
{
_id: 5,
a: UUID('d73f181e-cdda-42b4-b844-4d6e172e9bc8'),
score: 0.029335692524909973
},
{
_id: 2,
a: UUID('dee11d4e-63c6-4d90-983c-5c9f1e79e96c'),
score: 0.029335692524909973
}
]

考虑以下查询,使用文本操作符在 bhellousers字段中搜索 集合中的字符串 。然后,该查询按字段c 对结果进行排序,对于集合中的某些文档,该字段包含 null 值或缺失值。

要学习;了解更多信息,请参阅按空值和缺失值排序。

在升序排序过程中, Atlas Search默认会在结果顶部返回包含 null 或缺失值的文档,如以下示例所示:

db.users.aggregate([
{
"$search": {
"text": {
"path": "b",
"query": "hello"
},
"sort": { "c": 1 }
}
},
{
"$project": {
"_id": 1,
"c": 1,
"score": { "$meta": "searchScore" }
}
}
])
[
{ _id: 4, c: null, score: 0.029335692524909973 },
{ _id: 5, c: [], score: 0.029335692524909973 },
{ _id: 6, score: 0.029335692524909973 },
{ _id: 2, c: 'foo', score: 0.029335692524909973 },
{
_id: 3,
c: UUID('3be11d4e-62cb-4e95-9a3c-5c9f1e56c732'),
score: 0.029335692524909973
},
{
_id: 0,
c: ObjectId('507f1f77bcf86cd799439011'),
score: 0.029335692524909973
},
{ _id: 1, c: true, score: 0.029335692524909973 }
]

在降序排序期间, Atlas Search默认在结果底部返回包含 null 或缺失值的文档,如以下示例所示:

db.users.aggregate([
{
"$search": {
"text": {
"path": "b",
"query": "hello"
},
"sort": { "c": -1 }
}
},
{
"$project": {
"_id": 1,
"c": 1,
"score": { "$meta": "searchScore" }
}
}
])
[
{ _id: 1, c: true, score: 0.025981096550822258 },
{
_id: 0,
c: ObjectId('507f1f77bcf86cd799439011'),
score: 0.025981096550822258
},
{
_id: 3,
c: UUID('3be11d4e-62cb-4e95-9a3c-5c9f1e56c732'),
score: 0.025981096550822258
},
{ _id: 2, c: 'foo', score: 0.025981096550822258 },
{ _id: 4, c: null, score: 0.025981096550822258 },
{ _id: 5, c: [], score: 0.025981096550822258 },
{ _id: 6, score: 0.025981096550822258 }
]

注意

设置 noData: lowest 与默认相同。

如果您在升序排序期间将 noData字段指定为 lowest,则Atlas Search会在结果顶部返回包含 null 值或缺失值的文档,如以下示例所示。

db.users.aggregate([
{
"$search": {
"text": {
"path": "b",
"query": "hello"
},
"sort": {
"c": {
"order": 1,
"noData": "lowest"
}
}
}
},
{
"$project": {
"_id": 1,
"c": 1,
"score": { "$meta": "searchScore" }
}
}
])
[
{ _id: 4, c: null, score: 0.029335692524909973 },
{ _id: 5, c: [], score: 0.029335692524909973 },
{ _id: 6, score: 0.029335692524909973 },
{ _id: 2, c: 'foo', score: 0.029335692524909973 },
{
_id: 3,
c: UUID('3be11d4e-62cb-4e95-9a3c-5c9f1e56c732'),
score: 0.029335692524909973
},
{
_id: 0,
c: ObjectId('507f1f77bcf86cd799439011'),
score: 0.029335692524909973
},
{ _id: 1, c: true, score: 0.029335692524909973 }
]

如果您在降序排序期间将 noData字段指定为 lowest,Atlas Search在结果底部返回包含 null 值或缺失值的文档,如以下示例所示。

db.users.aggregate([
{
"$search": {
"text": {
"path": "b",
"query": "hello"
},
"sort": {
"c": {
"order": -1,
"noData": "lowest"
}
}
}
},
{
"$project": {
"_id": 1,
"c": 1,
"score": { "$meta": "searchScore" }
}
}
])
[
{ _id: 1, c: true, score: 0.025981096550822258 },
{
_id: 0,
c: ObjectId('507f1f77bcf86cd799439011'),
score: 0.025981096550822258
},
{
_id: 3,
c: UUID('3be11d4e-62cb-4e95-9a3c-5c9f1e56c732'),
score: 0.025981096550822258
},
{ _id: 2, c: 'foo', score: 0.025981096550822258 },
{ _id: 4, c: null, score: 0.025981096550822258 },
{ _id: 5, c: [], score: 0.025981096550822258 },
{ _id: 6, score: 0.025981096550822258 }
]

如果您在升序排序期间将 noData字段指定为 highest,则Atlas Search将在结果底部返回包含 null 值或缺失值的文档,如以下示例所示。

db.users.aggregate([
{
"$search": {
"text": {
"path": "b",
"query": "hello"
},
"sort": {
"c": {
"order": 1,
"noData": "highest"
}
}
}
},
{
"$project": {
"_id": 1,
"c": 1,
"score": { "$meta": "searchScore" }
}
}
])
[
{ _id: 2, c: 'foo', score: 0.025981096550822258 },
{
_id: 3,
c: UUID('3be11d4e-62cb-4e95-9a3c-5c9f1e56c732'),
score: 0.025981096550822258
},
{
_id: 0,
c: ObjectId('507f1f77bcf86cd799439011'),
score: 0.025981096550822258
},
{ _id: 1, c: true, score: 0.025981096550822258 },
{ _id: 4, c: null, score: 0.025981096550822258 },
{ _id: 5, c: [], score: 0.025981096550822258 },
{ _id: 6, score: 0.025981096550822258 }
]

如果您在降序排序期间将 noData字段指定为 highest,Atlas Search在结果顶部返回包含 null 值或缺失值的文档,如以下示例所示。

db.users.aggregate([
{
"$search": {
"text": {
"path": "b",
"query": "hello"
},
"sort": {
"c": {
"order": -1,
"noData": "highest"
}
}
}
},
{
"$project": {
"_id": 1,
"c": 1,
"score": { "$meta": "searchScore" }
}
}
])
[
{ _id: 4, c: null, score: 0.025981096550822258 },
{ _id: 5, c: [], score: 0.025981096550822258 },
{ _id: 6, score: 0.025981096550822258 },
{ _id: 1, c: true, score: 0.025981096550822258 },
{
_id: 0,
c: ObjectId('507f1f77bcf86cd799439011'),
score: 0.025981096550822258
},
{
_id: 3,
c: UUID('3be11d4e-62cb-4e95-9a3c-5c9f1e56c732'),
score: 0.025981096550822258
},
{ _id: 2, c: 'foo', score: 0.025981096550822258 }
]

具有 "_id": 4"_id": 5"_id": 6 的文档的顺序是随机的,因为Atlas Search在排序时将空值和缺失值视为相等。

考虑在给定另一文档且字段 中包含多类型大量的情况下,对c users集合进行以下查询:

db.users.insertOne({
"_id": 7,
"a": UUID("03e32aa9-1cbd-43b8-b9d6-18b171a03cc7"),
"b": "hello",
"c": [ false, null, 15 ]
})

以下使用文本操作符在搜索字段b hello中搜索字符串 ,并按字段c 对结果进行排序。

注意

在排序语法中设置noData: lowest 与默认相同。

对于升序排序, Atlas Search使用具有最低BSON类型的元素来表示多类型大量。默认下, Atlas Search将空值或缺失值视为最低BSON值。因此, Atlas Search使用 null 来表示具有 _id: 7 的文档的多类型大量,并在结果顶部返回此文档以及其他空值和缺失值。

要学习;了解更多信息,请参阅按空值和缺失值排序以及使用多种类型对数组进行排序。

db.users.aggregate([
{
"$search": {
"text": {
"path": "b",
"query": "hello"
},
"sort": {
"c": 1
}
}
},
{
"$project": {
"_id": 1,
"c": 1,
"score": { "$meta": "searchScore" }
}
}
])
[
{ _id: 4, c: null, score: 0.025981096550822258 },
{ _id: 5, c: [], score: 0.025981096550822258 },
{ _id: 6, score: 0.025981096550822258 }
{ _id: 7, c: [ false, null, 15 ], score: 0.025981096550822258 },
{ _id: 2, c: 'foo', score: 0.025981096550822258 },
{
_id: 3,
c: UUID('3be11d4e-62cb-4e95-9a3c-5c9f1e56c732'),
score: 0.025981096550822258
},
{
_id: 0,
c: ObjectId('507f1f77bcf86cd799439011'),
score: 0.025981096550822258
},
{ _id: 1, c: true, score: 0.025981096550822258 }
]

具有 "_id": 4"_id": 5"_id": 6"_id": 7 的文档的顺序是随机的,因为Atlas Search在排序时将空值和缺失值视为相等。

对于降序排序, Atlas Search使用具有最高BSON类型的元素来表示多类型大量。Atlas Search使用false 来表示具有_id: 7 的文档的多类型大量,因为这是大量中最高的BSON类型。由于Atlas Search还将 true 值排在 false 值之上,因此Atlas Search在具有 _id: 1 的文档之后返回此文档。

要学习;了解更多信息,请参阅按空值和缺失值排序以及使用多种类型对数组进行排序。

db.users.aggregate([
{
"$search": {
"text": {
"path": "b",
"query": "hello"
},
"sort": {
"c": -1
}
}
},
{
"$project": {
"_id": 1,
"c": 1,
"score": { "$meta": "searchScore" }
}
}
])
[
{ _id: 1, c: true, score: 0.025981096550822258 },
{ _id: 7, c: [ false, null, 15 ], score: 0.025981096550822258 },
{
_id: 0,
c: ObjectId('507f1f77bcf86cd799439011'),
score: 0.025981096550822258
},
{
_id: 3,
c: UUID('3be11d4e-62cb-4e95-9a3c-5c9f1e56c732'),
score: 0.025981096550822258
},
{ _id: 2, c: 'foo', score: 0.025981096550822258 }
{ _id: 4, c: null, score: 0.025981096550822258 },
{ _id: 5, c: [], score: 0.025981096550822258 },
{ _id: 6, score: 0.025981096550822258 },
]

具有 "_id": 4"_id": 5"_id": 6 的文档的顺序是随机的,因为Atlas Search在排序时将空值和缺失值视为相等。

以下查询指定noData: highest 以在排序期间将 null 值设立为最高BSON类型。

对于升序排序, Atlas Search使用具有最低BSON类型的元素来表示多类型大量。查询指定noData: highest 将空值或缺失值视为最高BSON值,因此Atlas Search使用15 表示具有_id: 7 的文档的多类型大量,因为数字是大量中下一个最低的BSON类型。

要学习;了解更多信息,请参阅按空值和缺失值排序以及使用多种类型对数组进行排序。

db.users.aggregate([
{
"$search": {
"text": {
"path": "b",
"query": "hello"
},
"sort": {
"c": {
"order": 1,
"noData": "highest"
}
}
}
},
{
"$project": {
"_id": 1,
"c": 1,
"score": { "$meta": "searchScore" }
}
}
])
[
{ _id: 7, c: [ false, null, 15 ], score: 0.025981096550822258 },
{ _id: 2, c: 'foo', score: 0.025981096550822258 },
{
_id: 3,
c: UUID('3be11d4e-62cb-4e95-9a3c-5c9f1e56c732'),
score: 0.025981096550822258
},
{
_id: 0,
c: ObjectId('507f1f77bcf86cd799439011'),
score: 0.025981096550822258
},
{ _id: 1, c: true, score: 0.025981096550822258 },
{ _id: 4, c: null, score: 0.025981096550822258 },
{ _id: 5, c: [], score: 0.025981096550822258 },
{ _id: 6, score: 0.025981096550822258 }
]

具有 "_id": 4"_id": 5"_id": 6 的文档的顺序是随机的,因为Atlas Search在排序时将空值和缺失值视为相等。

对于降序排序, Atlas Search使用具有最高BSON类型的元素来表示多类型大量。由于查询将noData 字段指定为highest ,以将空值或缺失值设立为最高BSON值,Atlas Search使用null 表示具有_id: 7 的文档的多类型大量,并在以下位置返回此文档:结果的顶部以及其他空值和缺失值。

要学习;了解更多信息,请参阅按空值和缺失值排序以及使用多种类型对数组进行排序。

db.users.aggregate([
{
"$search": {
"text": {
"path": "b",
"query": "hello"
},
"sort": {
"c": {
"order": -1,
"noData": "highest"
}
}
}
},
{
"$project": {
"_id": 1,
"c": 1,
"score": { "$meta": "searchScore" }
}
}
])
[
{ _id: 4, c: null, score: 0.025981096550822258 },
{ _id: 5, c: [], score: 0.025981096550822258 },
{ _id: 6, score: 0.025981096550822258 },
{ _id: 7, c: [ false, null, 15 ], score: 0.025981096550822258 },
{ _id: 1, c: true, score: 0.025981096550822258 },
{
_id: 0,
c: ObjectId('507f1f77bcf86cd799439011'),
score: 0.025981096550822258
},
{
_id: 3,
c: UUID('3be11d4e-62cb-4e95-9a3c-5c9f1e56c732'),
score: 0.025981096550822258
},
{ _id: 2, c: 'foo', score: 0.025981096550822258 }
]

具有 "_id": 4"_id": 5"_id": 6"_id": 7 的文档的顺序是随机的,因为Atlas Search在排序时将空值和缺失值视为相等。

以下查询在 sample_airbnb.listingsAndReviews 集合中搜索 Portugal 中的属性,并按 boolean 字段 is_location_exact 对结果进行降序排序。

该查询使用 $limit 阶段将输出限制为 5 个文档。它还使用 $project 阶段省略结果中除 nameproperty_typeaddress.countryaddress.location.is_location_exact 之外的所有字段。

1db.listingsAndReviews.aggregate([
2 {
3 "$search": {
4 "text": {
5 "path": "address.country",
6 "query": "Portugal"
7 },
8 "sort": {
9 "address.location.is_location_exact": -1,
10 }
11 }
12 },
13 {
14 "$limit": 5
15 },
16 {
17 "$project": {
18 "_id": 0,
19 "name": 1,
20 "property_type": 1,
21 "address.country": 1,
22 "address.location.is_location_exact": 1
23 }
24 }
25])
1[
2 {
3 name: 'BBC OPORTO 4X2',
4 property_type: 'Apartment',
5 address: { country: 'Portugal', location: { is_location_exact: true } }
6 },
7 {
8 name: 'Heroísmo IV',
9 property_type: 'Apartment',
10 address: { country: 'Portugal', location: { is_location_exact: true } }
11 },
12 {
13 name: 'Spacious and well located apartment',
14 property_type: 'Apartment',
15 address: { country: 'Portugal', location: { is_location_exact: true } }
16 },
17 {
18 name: 'Renovated Classic Design Studio with Sun Room',
19 property_type: 'Apartment',
20 address: { country: 'Portugal', location: { is_location_exact: true } }
21 },
22 {
23 name: "O'Porto Studio | Historic Center",
24 property_type: 'Loft',
25 address: { country: 'Portugal', location: { is_location_exact: true } }
26 }
27]

在前面的结果中,文档的 is_location_exact 值为 true,因为在降序排序中,Atlas Search 将 true 值排列在 false 值之上。如果通过将前面查询的第 9 行的值更改为 1 来执行升序排序,则 Atlas Search 会对 false 值高于 true 值的文档进行排名,并返回以下文档:

[
{
name: 'Ribeira Charming Duplex',
property_type: 'House',
address: { country: 'Portugal', location: { is_location_exact: false } }
},
{
name: 'Be Happy in Porto',
property_type: 'Loft',
address: { country: 'Portugal', location: { is_location_exact: false } }
},
{
name: 'Downtown Oporto Inn (room cleaning)',
property_type: 'Hostel',
address: { country: 'Portugal', location: { is_location_exact: false } }
},
{
name: 'A Casa Alegre é um apartamento T1.',
property_type: 'Apartment',
address: { country: 'Portugal', location: { is_location_exact: false } }
},
{
name: 'FloresRooms 3T',
property_type: 'Apartment',
address: { country: 'Portugal', location: { is_location_exact: false } }
}
]

以下查询使用 $search 阶段执行以下操作:

  • 搜索标题中含有dance字样的电影,优先搜索获得 2 个或更多奖项且在 1990 年 1 月 1 日之后上映的电影。

  • 按奖项数量降序对结果进行排序,然后按电影标题升序进行排序,然后按发行日期降序进行排序。

该查询使用$limit阶段将输出限制为10文档。 它还使用$project阶段执行以下操作:

  • 忽略结果中除 titlereleasedawards.wins 之外的所有字段。

  • 添加名为 score 的字段。

db.movies.aggregate([
{
"$search": {
"compound": {
"must": [{
"text": {
"path": "title",
"query": "dance"
}
}],
"should": [{
"range": {
"path": "awards.wins",
"gte": 2
}
}, {
"range": {
"path": "released",
"gte": ISODate("1990-01-01T00:00:00.000Z")
}
}]
},
"sort": {
"awards.wins": -1,
"title": 1,
"released": -1
}
}
},
{
"$limit": 10
},
{
"$project": {
"_id": 0,
"title": 1,
"released": 1,
"awards.wins": 1,
"score": { "$meta": "searchScore" }
}
}
])
[
{
title: 'Shall We Dance?',
released: ISODate("1997-07-11T00:00:00.000Z"),
awards: { wins: 57 },
score: 4.9811458587646484
},
{
title: 'Shall We Dance?',
released: ISODate("1997-07-11T00:00:00.000Z"),
awards: { wins: 57 },
score: 4.9811458587646484
},
{
title: 'War Dance',
released: ISODate("2008-11-01T00:00:00.000Z"),
awards: { wins: 11 },
score: 5.466421127319336
},
{
title: 'Dance with the Devil',
released: ISODate("1997-10-31T00:00:00.000Z"),
awards: { wins: 6 },
score: 4.615056037902832
},
{
title: 'Save the Last Dance',
released: ISODate("2001-01-12T00:00:00.000Z"),
awards: { wins: 6 },
score: 4.615056037902832
},
{
title: 'Dance with a Stranger',
released: ISODate("1985-08-09T00:00:00.000Z"),
awards: { wins: 4 },
score: 3.615056037902832
},
{
title: 'The Baby Dance',
released: ISODate("1998-08-23T00:00:00.000Z"),
awards: { wins: 4 },
score: 4.981145858764648
},
{
title: 'Three-Step Dance',
released: ISODate("2004-02-19T00:00:00.000Z"),
awards: { wins: 4 },
score: 4.981145858764648
},
{
title: "Cats Don't Dance",
released: ISODate("1997-03-26T00:00:00.000Z"),
awards: { wins: 3 },
score: 4.981145858764648
},
{
title: 'Dance Me Outside',
released: ISODate("1995-03-10T00:00:00.000Z"),
awards: { wins: 3 },
score: 4.981145858764648
}
]

以下查询使用 $search 阶段执行以下操作:

  • 使用范围操作符搜索 2010 年 1 月 1 日至 2015 年 1 月 1 日之间发布的电影。

  • 统计荣获 151015 奖项的电影数量。

  • 获取 2010-01-012011-01-012012-01-012013-01-012014-01-012015-01-01 发行的电影数量的计数。

  • 使用sort选项按发布日期降序排列结果。

该查询使用$limit阶段执行以下操作:

  • docs 输出字段中将输出限制为 5 个文档。

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

它使用$project阶段省略除awards.winsreleasedtitle字段之外的所有字段。

它还使用$replaceWith阶段将存储在$$SEARCH_META变量中的元数据结果包含在meta输出字段中,并使用$set阶段将meta字段添加到结果中。

db.movies.aggregate([
{
"$search": {
"facet": {
"operator": {
"range": {
"path": "released",
"gt": ISODate("2010-01-01T00:00:00.000Z"),
"lt": ISODate("2015-01-01T00:00:00.000Z")
}
},
"facets": {
"awardsFacet": {
"type": "number",
"path": "awards.wins",
"boundaries" : [1,5,10,15]
},
"releasedFacet" : {
"type" : "date",
"path" : "released",
"boundaries" : [ISODate("2010-01-01T00:00:00.000Z"), ISODate("2011-01-01T00:00:00.000Z"), ISODate("2012-01-01T00:00:00.000Z"), ISODate("2013-01-01T00:00:00.000Z"), ISODate("2014-01-01T00:00:00.000Z"), ISODate("2015-01-01T00:00:00.000Z")]
}
}
},
"sort": {
"released": -1
}
}
},
{
"$facet": {
"docs": [
{ "$limit": 5 },
{ "$project":
{
"_id": 0,
"title": 1,
"released": 1,
"awards.wins": 1
}
}
],
"meta": [
{"$replaceWith": "$$SEARCH_META"},
{"$limit": 1}
]
}
},
{
"$set": {
"meta": {
"$arrayElemAt": ["$meta", 0]
}
}
}
])
[
{
docs: [
{
title: 'Cold in July',
released: ISODate("2014-12-31T00:00:00.000Z"),
awards: { wins: 1 }
},
{
title: 'The Gambler',
released: ISODate("2014-12-31T00:00:00.000Z"),
awards: { wins: 7 }
},
{
title: 'Force Majeure',
released: ISODate("2014-12-30T00:00:00.000Z"),
awards: { wins: 31 }
},
{
title: 'LFO',
released: ISODate("2014-12-27T00:00:00.000Z"),
awards: { wins: 3 }
},
{
title: 'Peace After Marriage',
released: ISODate('2014-12-26T00:00:00.000Z'),
awards: { wins: 5 }
}
],
meta: {
count: { lowerBound: Long("4821") },
facet: {
releasedFacet: {
buckets: [
{
_id: ISODate("2010-01-01T00:00:00.000Z"),
count: Long("857")
},
{
_id: ISODate("2011-01-01T00:00:00.000Z"),
count: Long("909")
},
{
_id: ISODate("2012-01-01T00:00:00.000Z"),
count: Long("903")
},
{
_id: ISODate("2013-01-01T00:00:00.000Z"),
count: Long("1063")
},
{
_id: ISODate("2014-01-01T00:00:00.000Z"),
count: Long("1089")
}
]
},
awardsFacet: {
buckets: [
{ _id: 1, count: Long("2330") },
{ _id: 5, count: Long("604") },
{ _id: 10, count: Long("233") }
]
}
}
}
}
}
]

以下示例演示如何按结果中文档的分数对结果进行排序。这些示例演示了如何执行以下操作:

  • 首先按升序对结果进行排序,以检索分数最低的文档。

  • 按分数对结果进行降序排序,对分数相同的结果任意排序。

  • 按分数对结果进行排序,对于具有相同分数的结果,使用唯一字段进行排序。

以下查询使用 $search 阶段执行以下操作:

  • 搜索标题中包含“story”一词的电影。

  • 按分数升序对结果进行排序。

该查询使用$limit阶段将输出限制为5文档。 它还使用$project阶段执行以下操作:

  • 忽略结果中除 title 之外的所有字段。

  • 添加名为 score 的字段。

db.movies.aggregate([
{
"$search": {
"text": {
"path": "title",
"query": "story"
},
"sort": {score: {$meta: "searchScore", order: 1}}
}
},
{
"$limit": 5
},
{
"$project": {
"_id": 0,
"title": 1,
"score": {$meta: "searchScore"}
}
}
])
[
{
title: 'Do You Believe in Miracles? The Story of the 1980 U.S. Hockey Team',
score: 0.8674521446228027
},
{
title: 'Once in a Lifetime: The Extraordinary Story of the New York Cosmos',
score: 0.9212141036987305
},
{
title: 'The Source: The Story of the Beats and the Beat Generation',
score: 0.9820802211761475
},
{
title: 'If These Knishes Could Talk: The Story of the NY Accent',
score: 0.9820802211761475
},
{
title: 'Dream Deceivers: The Story Behind James Vance vs. Judas Priest',
score: 1.051558256149292
}
]

以下查询使用 $search 阶段执行以下操作:

  • 搜索标题中包含“summer”一词的电影。

  • 按分数对结果进行降序排序,对分数相同的结果任意排序。

该查询使用$limit阶段将输出限制为5文档。 它还使用$project阶段执行以下操作:

  • 忽略结果中除 _idtitle 之外的所有字段。

  • 添加名为 score 的字段。

db.movies.aggregate([
{
"$search": {
"text": {
"path": "title",
"query": "summer"
},
"sort": {score: {$meta: "searchScore"}}
}
},
{
"$limit": 5
},
{
"$project": {
"_id": 1,
"title": 1,
"score": {$meta: "searchScore"}
}
}
])
[
{
_id: ObjectId("573a1398f29313caabcea21e"),
title: 'Summer',
score: 3.5844719409942627
},
{
_id: ObjectId("573a13a6f29313caabd18eca"),
title: 'Summer Things',
score: 3.000213623046875
},
{
_id: ObjectId("573a13b8f29313caabd4c1d0"),
title: 'Summer Palace',
score: 3.000213623046875
},
{
_id: ObjectId("573a1394f29313caabcde8e8"),
title: 'Summer Stock',
score: 3.000213623046875
},
{
_id: ObjectId("573a13acf29313caabd284fa"),
title: 'Wolf Summer',
score: 3.000213623046875
}
]

以下查询使用 $search 阶段执行以下操作:

  • 搜索标题中包含“prince”一词的电影。

  • 对于分数相同的结果,首先按分数对结果进行排序,然后按 released 字段的值按升序排序。

该查询使用$limit阶段将输出限制为5文档。 它还使用$project阶段执行以下操作:

  • 忽略结果中除 titlereleased 之外的所有字段。

  • 添加名为 score 的字段。

db.movies.aggregate([
{
"$search": {
"text": {
"path": "title",
"query": "prince"
},
"sort": {score: {$meta: "searchScore"}, "released": 1}
}
},
{
"$limit": 5
},
{
"$project": {
"_id": 0,
"title": 1,
"released": 1,
"score": {$meta: "searchScore"}
}
}
])
[
{
title: 'Prince',
released: ISODate("2015-08-14T00:00:00.000Z"),
score: 4.168826103210449
},
{
title: 'Prince Avalanche',
released: ISODate("2013-09-19T00:00:00.000Z"),
score: 3.4893198013305664
},
{
title: 'The Prince',
released: ISODate("2014-08-22T00:00:00.000Z"),
score: 3.4893198013305664
},
{
title: 'Prince of Foxes',
released: ISODate("1949-12-23T00:00:00.000Z"),
score: 3.0002830028533936
},
{
title: 'The Oil Prince',
released: ISODate("1966-01-01T00:00:00.000Z"),
score: 3.0002830028533936
}
]

后退

分数详情