Docs 菜单
Docs 主页
/
Atlas
/ /

如何跨多个集合运行 Atlas 搜索查询

本页面包含教程,演示了如何在多个 Atlas 集合中运行 Atlas Search 查询的不同方法:

  • 要加入集合并在其中进行搜索,请使用 $lookup with $search。

  • 要合并多个集合的搜索结果,请将 $unionWith 与 $ 搜索一起使用。

  • 要整合多个集合以便一起对它们索引和搜索,请使用物化视图。

在开始之前,请确保您的 Atlas 集群满足先决条件中所述的要求。


➤ 使用此页面上的选择语言下拉菜单设立此页面上示例的语言。


从 v6.0 开始, MongoDB$lookup 聚合阶段支持$search $lookuppipeline选项内的 。使用$lookup ,您可以在查询时联接同一数据库中的多个集合,并运行$search 查询以进一步缩小搜索。

本教程演示针对 sample_analytics 数据库中的 accountscustomers 集合,如何运行带有 $search$lookup 查询。本教程将引导您完成以下步骤:

  1. sample_analytics 数据库的 accounts 集合上创建默认的 Atlas Search 索引。

  2. 使用 $search 运行 $lookup 查询,从 customers 集合中查找其帐号同时购买了 accounts 集合中 CurrencyServiceInvestmentStock 产品的客户。

要使用 $search 运行 $lookup 查询,您的集群必须运行 MongoDB 6.0 或更高版本。要升级您的 MongoDB 版本,请参阅为集群升级 MongoDB 主版本。

$lookup 查询的表现欠佳,因为 Atlas Search 会在数据库中对集合中的每个文档进行全文档查找。

要了解更多信息,请参阅减少 $lookup 操作。

sample_analytics.accounts 集合中的所有字段上创建名为 lookup-with-search-tutorial 的 Atlas Search 索引。

1

警告

导航改进正在进行中

我们目前正在推出改进的全新导航体验。如果以下步骤与Atlas用户界面中的视图不匹配,请参阅预览文档。

  1. 如果尚未显示,请从导航栏上的 Organizations 菜单中选择包含所需项目的组织。

  2. 如果尚未显示,请从导航栏的Projects菜单中选择所需的项目。

  3. 如果尚未出现,请单击侧边栏中的 Clusters(集群)。

    会显示集群页面。

2

您可以从侧边栏、 Data Explorer 或集群详细信息页面转到 Atlas Search 页面。

  1. 在侧边栏中,单击 Services 标题下的 Atlas Search

    如果没有集群,则请单击 Create cluster 来创建一个。要了解更多信息,请参阅创建集群

  2. 如果您的项目有多个集群,请从 Select cluster 下拉列表中选择要使用的集群,然后单击 Go to Atlas Search

    将显示 Atlas Search 页面。

  1. 单击集群的对应 Browse Collections 按钮。

  2. 展开数据库并选择集合。

  3. 单击该集合的 Search Indexes 标签页。

    将显示 Atlas Search 页面。

  1. 单击集群的名称。

  2. 单击 Atlas Search 标签页。

    将显示 Atlas Search 页面。

3
4

在页面上进行以下选择,然后单击 Next

Search Type

选择 Atlas Search 索引类型。

Index Name and Data Source

指定以下信息:

  • Index Name: lookup-with-search-tutorial

  • Database and Collection:

    • sample_analytics database

    • accounts 集合

Configuration Method

For a guided experience, select Visual Editor.

To edit the raw index definition, select JSON Editor.

注意

您的 Atlas Search 索引默认名为 default。如果保留此名称,则对于任何未在其操作符中指定不同 index选项的 Atlas Search 查询,您的搜索索引将成为默认搜索索引。如果您要创建多个索引,我们建议您在所有索引中保持一致且具有描述性的命名规则。

5

以下索引定义对集合中的支持类型字段动态创建索引。您可以使用 Atlas Search Visual Editor 或 Atlas Search JSON Editor 在 Atlas 用户界面中创建索引。

查看集合的默认索引定义。

  1. 查看索引定义。

    索引定义应类似于以下内容:

    {
    "mappings": {
    "dynamic": true
    }
    }
  2. 单击 Next(连接)。

6
7

此时将显示一个模态窗口,让您知道索引正在构建中。单击 Close 按钮。

8

构建索引大约需要一分钟时间。在构建时,Status 列显示 Build in Progress。构建完成后,Status 列显示 Active


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


连接到您的 Atlas 集群,针对 sample_analytics 数据库中的索引集合运行样本查询。

1

在终端窗口中打开mongosh并连接到集群。 有关连接的详细说明,请参阅通过mongosh连接。

2

mongosh 提示符下运行以下命令:

use sample_analytics
switched to db sample_analytics
3

以下查询使用以下阶段:

  • $lookup 以执行以下操作:

    • 根据客户的账户 ID 连接 sample_analytics 数据库中的 customersaccounts 集合,并在名为 purchases 的数组字段中返回 accounts 集合中的匹配文档。

    • 使用子管道中的 $search 阶段搜索 must 已购买 CurrencyServiceInvestmentStock 的客户帐户,并优先选择介于 500010000 之间的订单限制。

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

  • $project 阶段以排除结果中的指定字段。

db.customers.aggregate([
{
$lookup:{
"from": "accounts",
"localField": "accounts",
"foreignField": "account_id",
"as": "purchases",
"pipeline": [{
"$search": {
"index": "lookup-with-search-tutorial",
"compound": {
"must": [{
"queryString": {
"defaultPath": "products",
"query": "products: (CurrencyService AND InvestmentStock)"
}
}],
"should": [{
"range": {
"path": "limit",
"gte": 5000,
"lte": 10000
}
}]
}
}
},{
"$project": {
"_id": 0
}
}]
}
},{
"$limit": 5
},{
"$project": {
"_id": 0,
"address": 0,
"birthdate": 0,
"username": 0,
"tier_and_details": 0
}
}
])
[
{
name: 'Elizabeth Ray',
email: 'arroyocolton@gmail.com',
active: true,
accounts: [ 371138, 324287, 276528, 332179, 422649, 387979 ],
purchases: [
{
account_id: 422649,
limit: 10000,
products: [ 'CurrencyService', 'InvestmentStock' ]
},
{
account_id: 324287,
limit: 10000,
products: [
'Commodity',
'CurrencyService',
'Derivatives',
'InvestmentStock'
]
},
{
account_id: 332179,
limit: 10000,
products: [
'Commodity',
'CurrencyService',
'InvestmentFund',
'Brokerage',
'InvestmentStock'
]
}
]
},
{
name: 'Lindsay Cowan',
email: 'cooperalexis@hotmail.com',
accounts: [ 116508 ],
purchases: []
},
{
name: 'Katherine David',
email: 'timothy78@hotmail.com',
accounts: [ 462501, 228290, 968786, 515844, 377292 ],
purchases: [
{
account_id: 228290,
limit: 10000,
products: [
'CurrencyService',
'InvestmentStock',
'InvestmentFund',
'Brokerage'
]
},
{
account_id: 515844,
limit: 10000,
products: [
'Commodity',
'CurrencyService',
'InvestmentFund',
'Brokerage',
'InvestmentStock'
]
}
]
},
{
name: 'Leslie Martinez',
email: 'tcrawford@gmail.com',
accounts: [ 170945, 951849 ],
purchases: []
},
{
name: 'Brad Cardenas',
email: 'dustin37@yahoo.com',
accounts: [ 721914, 817222, 973067, 260799, 87389 ],
purchases: [
{
account_id: 87389,
limit: 10000,
products: [ 'CurrencyService', 'InvestmentStock' ]
},
{
account_id: 260799,
limit: 10000,
products: [
'Brokerage',
'InvestmentStock',
'Commodity',
'CurrencyService'
]
}
]
}
]
1

打开 MongoDB Compass 并连接到您的集群。有关连接的详细说明,请参阅通过 Compass 连接。

2

Database 屏幕上,依次单击 sample_analytics 数据库和 customers 集合。

3

以下查询使用以下阶段:

  • $lookup 以执行以下操作:

    • 根据客户的账户 ID 连接 sample_analytics 数据库中的 customersaccounts 集合,并在名为 purchases 的数组字段中返回 accounts 集合中的匹配文档。

    • 使用子管道中的 $search 阶段搜索 must 已购买 CurrencyServiceInvestmentStock 的客户帐户,并优先选择介于 500010000 之间的订单限制。

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

  • $project 阶段以排除结果中的指定字段。

若要在 MongoDB Compass 中运行此查询:

  1. 单击 Aggregations 标签页。

  2. 单击 Select...,然后从下拉菜单中选择阶段并为该阶段添加查询,以配置以下每个管道阶段。单击 Add Stage 以添加其他阶段。

    管道阶段
    查询

    $lookup

    {
    from: "accounts",
    localField: "accounts",
    foreignField: "account_id",
    as: "purchases",
    pipeline: [
    {
    $search: {
    index: "lookup-with-search-tutorial",
    compound: {
    must: [
    {
    queryString: {
    defaultPath: "products",
    query:
    "products: (CurrencyService AND InvestmentStock)"
    }
    }
    ],
    should: [
    {
    range: {
    path: "limit",
    gte: 5000,
    lte: 10000,
    }
    }
    ]
    }
    }
    },
    {
    $project: {
    _id: 0,
    }
    }
    ]
    }

    $limit

    5

    $project

    {
    _id: 0,
    address: 0,
    birthdate: 0,
    username: 0,
    tier_and_details: 0,
    }

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

    name: Elizabeth Ray
    email: arroyocolton@gmail.com
    active: True
    accounts: Array (6)
    purchases: Array (3)
    name: "Lindsay Cowan"
    email: "cooperalexis@hotmail.com"
    accounts: Array (1)
    purchases: Array (empty)
    name: "Katherine David"
    email: "timothy78@hotmail.com"
    accounts: Array (5)
    urchases: Array (2)
    name: "Leslie Martinez"
    email: "tcrawford@gmail.com"
    accounts: Array (2)
    purchases: Array (empty)
    name: "Brad Cardenas"
    email: "dustin37@yahoo.com"
    accounts: Array (5)
    purchases: Array (2)
4

对于在结果中返回的文档,MongoDB Compass 可能不会显示该文档对象内的所有字段和数组内的所有值。如要查看所有字段和值,请展开结果中的字段。

1
  1. 创建一个名为 lookup-with-search 的新目录,并使用 dotnet new 命令初始化项目。

    mkdir lookup-with-search
    cd lookup-with-search
    dotnet new console
  2. 将 .NET/C# 驱动程序作为依赖项添加到项目中。

    dotnet add package MongoDB.Driver
2

以下查询使用以下阶段:

  • $lookup 以执行以下操作:

    • 根据客户的账户 ID 连接 sample_analytics 数据库中的 customersaccounts 集合,并在名为 purchases 的数组字段中返回 accounts 集合中的匹配文档。

    • 使用子管道中的 $search 阶段搜索 must 已购买 CurrencyServiceInvestmentStock 的客户帐户,并优先选择介于 500010000 之间的订单限制。

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

  • $project 阶段以排除结果中的指定字段。

1using MongoDB.Bson;
2using MongoDB.Bson.Serialization.Attributes;
3using MongoDB.Bson.Serialization.Conventions;
4using MongoDB.Driver;
5using MongoDB.Driver.Core;
6using MongoDB.Driver.Search;
7
8public class LookupWithSearch{
9
10 static void Main(string[] args) {// allow automapping of the camelCase database fields to our MovieDocument
11 var camelCaseConvention = new ConventionPack { new CamelCaseElementNameConvention() };
12 ConventionRegistry.Register("CamelCase", camelCaseConvention, type => true);
13
14 // connect to your Atlas cluster
15 var mongoClient = new MongoClient("<connection-string>");
16
17 // define namespace
18 var analyticsDatabase = mongoClient.GetDatabase("sample_analytics");
19 var accountsCollection = analyticsDatabase.GetCollection<AccountDocument>("accounts");
20 var customersCollection = analyticsDatabase.GetCollection<CustomerDocument>("customers");
21
22 // define pipeline stages
23 var lookupStage = new BsonDocument("$lookup", new BsonDocument{
24 { "from", "accounts" }, { "localField", "accounts" }, { "foreignField", "account_id" },
25 { "as", "purchases" }, { "pipeline", new BsonArray{
26 new BsonDocument("$search", new BsonDocument{
27 { "index", "lookup-with-search-tutorial" }, { "compound", new BsonDocument{
28 { "must", new BsonArray{
29 new BsonDocument("queryString", new BsonDocument{
30 { "defaultPath", "products" }, { "query", "products: (CurrencyService AND InvestmentStock)" }
31 })
32 }},
33 { "should", new BsonArray{
34 new BsonDocument("range", new BsonDocument{
35 { "path", "limit" }, { "gte", 5000 }, { "lte", 10000 }
36 })
37 }}
38 }}
39 })
40 }}
41 });
42 var projectStage1 = new BsonDocument("$project", new BsonDocument("_id", 0));
43 var limitStage = new BsonDocument("$limit", 5);
44 var projectStage2 = new BsonDocument("$project", new BsonDocument{
45 { "_id", 0 }, { "address", 0 }, { "birthdate", 0 }, { "username", 0 }, { "tier_and_details", 0 }
46 });
47 var aggregationPipeline = new List<BsonDocument> {lookupStage, projectStage1, limitStage, projectStage2};
48
49 // run pipeline
50 var results = customersCollection.Aggregate<BsonDocument>(aggregationPipeline).ToList();
51
52 // print results
53 foreach (var acct in results) {
54 Console.WriteLine(acct.ToJson());
55 }
56 }
57}
58
59// define fields in the accounts collection
60[BsonIgnoreExtraElements]
61public class AccountDocument {
62 [BsonId]
63 [BsonRepresentation(BsonType.ObjectId)]
64 [BsonElement("_id")]
65 public string Id { get; set; }
66
67 [BsonElement("account_id")]
68 public int AccountId { get; set; }
69
70 [BsonElement("limit")]
71 public int Limit { get; set; }
72}
73
74// define fields in the customers collection
75[BsonIgnoreExtraElements]
76public class CustomerDocument {
77 [BsonId]
78 [BsonRepresentation(BsonType.ObjectId)]
79 [BsonElement("_id")]
80 public ObjectId Id { get; set; }
81
82 [BsonElement("name")]
83 public string Name { get; set; }
84
85 [BsonElement("email")]
86 public string Email { get; set; }
87
88 [BsonElement("active")]
89 public bool Active { get; set; }
90
91 [BsonElement("accounts")]
92 public List<int> Accounts { get; set; }
93}
94
95// define new array field for matching documents
96public class CustomerLookedUp: CustomerDocument{
97 public List<CustomerDocument> Purchases { get; set; }
98}
3

确保您的连接字符串包含数据库用户的档案。要了解详情,请参阅通过驱动程序连接

4
dotnet run lookup-with-search.csproj
{
"name" : "Elizabeth Ray",
"email" : "arroyocolton@gmail.com",
"active" : true,
"accounts" : [371138, 324287, 276528, 332179, 422649,
387979],
"purchases" : [
{
"_id" : ObjectId("5ca4bbc7a2dd94ee58162402"),
"account_id" : 422649,
"limit" : 10000,
"products" : ["CurrencyService", "InvestmentStock"]
},
{
"_id" : ObjectId("5ca4bbc7a2dd94ee581623a9"),
"account_id" : 324287,
"limit" : 10000,
"products" : ["Commodity", "CurrencyService", "Derivatives", "InvestmentStock"]
},
{
"_id" : ObjectId("5ca4bbc7a2dd94ee58162400"),
"account_id" : 332179,
"limit" : 10000,
"products" : ["Commodity", "CurrencyService", "InvestmentFund", "Brokerage", "InvestmentStock"]
}
]
}
{
"name" : "Lindsay Cowan",
"email" : "cooperalexis@hotmail.com",
"accounts" : [116508],
"purchases" : []
}
{
"name" : "Katherine David",
"email" : "timothy78@hotmail.com",
"accounts" : [462501, 228290, 968786, 515844, 377292],
"purchases" : [
{
"_id" : ObjectId("5ca4bbc7a2dd94ee581623c9"),
"account_id" : 228290,
"limit" : 10000,
"products" : ["CurrencyService", "InvestmentStock", "InvestmentFund", "Brokerage"] },
{
"_id" : ObjectId("5ca4bbc7a2dd94ee581623cb"),
"account_id" : 515844,
"limit" : 10000,
"products" : ["Commodity", "CurrencyService", "InvestmentFund", "Brokerage", "InvestmentStock"]
}
]
}
{
"name" : "Leslie Martinez",
"email" : "tcrawford@gmail.com",
"accounts" : [170945, 951849],
"purchases" : []
}
{
"name" : "Brad Cardenas",
"email" : "dustin37@yahoo.com",
"accounts" : [721914, 817222, 973067, 260799, 87389],
"purchases" : [
{
"_id" : ObjectId("5ca4bbc7a2dd94ee581623d6"),
"account_id" : 87389,
"limit" : 10000,
"products" : ["CurrencyService", "InvestmentStock"] },
{
"_id" : ObjectId("5ca4bbc7a2dd94ee581623d5"),
"account_id" : 260799,
"limit" : 10000,
"products" : ["Brokerage", "InvestmentStock", "Commodity", "CurrencyService"]
}
]
}
1
2

以下查询使用以下阶段:

  • $lookup 以执行以下操作:

    • 根据客户的账户 ID 连接 sample_analytics 数据库中的 customersaccounts 集合,并在名为 purchases 的数组字段中返回 accounts 集合中的匹配文档。

    • 使用子管道中的 $search 阶段搜索 must 已购买 CurrencyServiceInvestmentStock 的客户帐户,并优先选择介于 500010000 之间的订单限制。

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

  • $project 阶段以排除结果中的指定字段。

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 var err error
15 // connect to the Atlas cluster
16 ctx := context.Background()
17 clOpts := options.Client().ApplyURI("<connection-string>").SetTimeout(5 * time.Second)
18 client, err := mongo.Connect(clOpts)
19 if err != nil {
20 panic(err)
21 }
22 defer client.Disconnect(ctx)
23 // set namespace
24 collection := client.Database("sample_analytics").Collection("customers")
25 // define pipeline
26 lookupStage := bson.D{{Key: "$lookup", Value: bson.D{
27 {Key: "from", Value: "accounts"},
28 {Key: "localField", Value: "accounts"},
29 {Key: "foreignField", Value: "account_id"},
30 {Key: "as", Value: "purchases"},
31 {Key: "pipeline", Value: bson.A{
32 bson.D{
33 {Key: "$search", Value: bson.D{
34 {Key: "index", Value: "lookup-with-search-tutorial"},
35 {Key: "compound", Value: bson.D{
36 {Key: "must", Value: bson.A{
37 bson.D{{Key: "queryString", Value: bson.D{
38 {Key: "defaultPath", Value: "products"},
39 {Key: "query", Value: "products: (CurrencyService AND InvestmentStock)"},
40 }}},
41 }},
42 {Key: "should", Value: bson.A{
43 bson.D{{Key: "range", Value: bson.D{
44 {Key: "path", Value: "limit"},
45 {Key: "gte", Value: 5000},
46 {Key: "lte", Value: 10000},
47 }}},
48 }},
49 }},
50 }},
51 },
52 bson.D{{Key: "$project", Value: bson.D{
53 {Key: "_id", Value: 0},
54 {Key: "address", Value: 0},
55 {Key: "birthdate", Value: 0},
56 {Key: "username", Value: 0},
57 {Key: "tier_and_details", Value: 0},
58 }}},
59 }},
60 }}}
61 limitStage := bson.D{{Key: "$limit", Value: 5}}
62 projectStage := bson.D{{Key: "$project", Value: bson.D{
63 {Key: "name", Value: 1},
64 {Key: "email", Value: 1},
65 {Key: "active", Value: 1},
66 {Key: "accounts", Value: 1},
67 {Key: "purchases", Value: 1},
68 }}}
69
70 // run pipeline
71 cursor, err := collection.Aggregate(ctx, mongo.Pipeline{lookupStage, limitStage, projectStage})
72 if err != nil {
73 panic(err)
74 }
75 // print results
76 var results []bson.D
77 if err = cursor.All(context.TODO(), &results); err != nil {
78 panic(err)
79 }
80 for _, result := range results {
81 fmt.Println(result)
82 }
83}
3

确保您的连接字符串包含数据库用户的档案。要了解详情,请参阅通过驱动程序连接

4
go run lookup-with-search-query.go
{"_id":...,"name":"Gary Nichols","email":"laura34@yahoo.com","accounts":[{"$numberInt":"385397"},{"$numberInt":"337979"},{"$numberInt":"325377"},{"$numberInt":"440243"},{"$numberInt":"586395"},{"$numberInt":"86702"}],"purchases":[{"account_id":{"$numberInt":"337979"},"limit":{"$numberInt":"10000"},"products":["Brokerage","Derivatives","InvestmentStock","CurrencyService"]}]}
{"_id":...,"name":"Ashley Lopez","email":"michael16@hotmail.com","accounts":[{"$numberInt":"662207"},{"$numberInt":"816481"}],"purchases":[]}
{"_id":...,"name":"John Parks","email":"zmelton@gmail.com","accounts":[{"$numberInt":"702610"},{"$numberInt":"240640"}],"purchases":[{"account_id":{"$numberInt":"702610"},"limit":{"$numberInt":"10000"},"products":["Commodity","CurrencyService","InvestmentStock"]}]}
{"_id":...,"name":"Jennifer Lawrence","email":"scott50@yahoo.com","accounts":[{"$numberInt":"344885"},{"$numberInt":"839927"},{"$numberInt":"853542"}],"purchases":[{"account_id":{"$numberInt":"853542"},"limit":{"$numberInt":"10000"},"products":["CurrencyService","InvestmentStock"]},{"account_id":{"$numberInt":"344885"},"limit":{"$numberInt":"10000"},"products":["Commodity","InvestmentFund","CurrencyService","InvestmentStock"]},{"account_id":{"$numberInt":"839927"},"limit":{"$numberInt":"10000"},"products":["InvestmentFund","CurrencyService","Brokerage","Commodity","InvestmentStock"]}]}
{"_id":...,"name":"Jacqueline Haynes","email":"virginia36@hotmail.com","accounts":[{"$numberInt":"631901"},{"$numberInt":"814687"}],"purchases":[]}
1

junit

4.11 或更高版本

mongodb-driver-sync

4.3.0 或更高版本

slf4j-log4j12

1.7.30 或更高版本

2
3

以下查询使用以下阶段:

  • $lookup 以执行以下操作:

    • 根据客户的账户 ID 连接 sample_analytics 数据库中的 customersaccounts 集合,并在名为 purchases 的数组字段中返回 accounts 集合中的匹配文档。

    • 使用子管道中的 $search 阶段搜索 must 已购买 CurrencyServiceInvestmentStock 的客户帐户,并优先选择介于 500010000 之间的订单限制。

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

  • $project 阶段以排除结果中的指定字段。

1import static com.mongodb.client.model.Aggregates.limit;
2import static com.mongodb.client.model.Aggregates.project;
3import static com.mongodb.client.model.Projections.*;
4import java.util.Arrays;
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 LookupWithSearchQuery {
12
13 public static void main(String[] args) {
14 // connect to your Atlas cluster
15 String uri = "<connection-string>";
16
17 try (MongoClient mongoClient = MongoClients.create(uri)) {
18 // set namespace
19 MongoDatabase database = mongoClient.getDatabase("sample_analytics");
20 MongoCollection<Document> collection = database.getCollection("customers");
21
22 // define pipeline
23 Document agg = new Document("$lookup",
24 new Document("from", "accounts")
25 .append("localField", "accounts")
26 .append("foreignField", "account_id")
27 .append("as", "purchases")
28 .append("pipeline", Arrays.asList(new Document("$search",
29 new Document("index", "lookup-with-search-tutorial")
30 .append("compound",
31 new Document("must", Arrays.asList(new Document("queryString",
32 new Document("defaultPath", "products")
33 .append("query", "products: (CurrencyService AND InvestmentStock)"))))
34 .append("should", Arrays.asList(new Document("range",
35 new Document("path", "limit")
36 .append("gte", 5000L)
37 .append("lte", 10000L)
38 )))
39 )
40 ),
41 new Document("$limit", 5L),
42 new Document("$project",
43 new Document("_id", 0L)
44 .append("address", 0L)
45 .append("birthdate", 0L)
46 .append("username", 0L)
47 .append("tier_and_details", 0L)
48 )))
49 );
50 // run pipeline and print results
51 collection.aggregate(Arrays.asList(agg,
52 limit(5),
53 project(fields(excludeId(), include("name", "email", "active", "accounts", "purchases")))
54 ))
55 .forEach(doc -> System.out.println(doc.toJson()));
56 }
57 }
58}

注意

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

package com.mongodb.drivers;
4

确保您的连接字符串包含数据库用户的档案。要了解详情,请参阅通过驱动程序连接

5
javac LookupWithSearchQuery.java
java LookupWithSearchQuery
{"name": "Elizabeth Ray", "email": "arroyocolton@gmail.com", "active": true, "accounts": [371138, 324287, 276528, 332179, 422649, 387979], "purchases": [{"account_id": 422649, "limit": 10000, "products": ["CurrencyService", "InvestmentStock"]}, {"account_id": 324287, "limit": 10000, "products": ["Commodity", "CurrencyService", "Derivatives", "InvestmentStock"]}, {"account_id": 332179, "limit": 10000, "products": ["Commodity", "CurrencyService", "InvestmentFund", "Brokerage", "InvestmentStock"]}]}
{"name": "Lindsay Cowan", "email": "cooperalexis@hotmail.com", "accounts": [116508], "purchases": []}
{"name": "Katherine David", "email": "timothy78@hotmail.com", "accounts": [462501, 228290, 968786, 515844, 377292], "purchases": [{"account_id": 228290, "limit": 10000, "products": ["CurrencyService", "InvestmentStock", "InvestmentFund", "Brokerage"]}, {"account_id": 515844, "limit": 10000, "products": ["Commodity", "CurrencyService", "InvestmentFund", "Brokerage", "InvestmentStock"]}]}
{"name": "Leslie Martinez", "email": "tcrawford@gmail.com", "accounts": [170945, 951849], "purchases": []}
{"name": "Brad Cardenas", "email": "dustin37@yahoo.com", "accounts": [721914, 817222, 973067, 260799, 87389], "purchases": [{"account_id": 87389, "limit": 10000, "products": ["CurrencyService", "InvestmentStock"]}, {"account_id": 260799, "limit": 10000, "products": ["Brokerage", "InvestmentStock", "Commodity", "CurrencyService"]}]}
1

mongodb-driver-kotlin-coroutine

4.10.0 或更高版本

2
3

以下查询使用以下阶段:

  • $lookup 以执行以下操作:

    • 根据客户的账户 ID 连接 sample_analytics 数据库中的 customersaccounts 集合,并在名为 purchases 的数组字段中返回 accounts 集合中的匹配文档。

    • 使用子管道中的 $search 阶段搜索 must 已购买 CurrencyServiceInvestmentStock 的客户帐户,并优先选择介于 500010000 之间的订单限制。

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

  • $project 阶段以排除结果中的指定字段。

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.util.*
8
9fun main() {
10 // connect to your Atlas cluster
11 val uri = "<connection-string>"
12 val mongoClient = MongoClient.create(uri)
13
14 // set namespace
15 val database = mongoClient.getDatabase("sample_analytics")
16 val collection = database.getCollection<Document>("customers")
17
18 runBlocking {
19 // define pipeline
20 val agg = Document(
21 "\$lookup",
22 Document("from", "accounts")
23 .append("localField", "accounts")
24 .append("foreignField", "account_id")
25 .append("as", "purchases")
26 .append(
27 "pipeline", Arrays.asList(
28 Document(
29 "\$search",
30 Document("index", "lookup-with-search-tutorial")
31 .append(
32 "compound",
33 Document(
34 "must", Arrays.asList(
35 Document(
36 "queryString",
37 Document("defaultPath", "products")
38 .append("query", "products: (CurrencyService AND InvestmentStock)")
39 )
40 )
41 )
42 .append(
43 "should", Arrays.asList(
44 Document(
45 "range",
46 Document("path", "limit")
47 .append("gte", 5000)
48 .append("lte", 10000)
49 )
50 )
51 )
52 )
53 ),
54 Document("\$limit", 5),
55 Document(
56 "\$project",
57 Document("_id", 0)
58 .append("address", 0)
59 .append("birthdate", 0)
60 .append("username", 0)
61 .append("tier_and_details", 0)
62 )
63 )
64 )
65 )
66
67 // run pipeline and print results
68 val resultsFlow = collection.aggregate<Document>(
69 listOf(
70 agg,
71 limit(5),
72 project(fields(excludeId(), include("name", "email", "active", "accounts", "purchases")))
73 )
74 )
75 resultsFlow.collect { println(it) }
76 }
77 mongoClient.close()
78}
4

确保您的连接字符串包含数据库用户的档案。要了解详情,请参阅通过驱动程序连接

5

当你在 IDE 中运行 LookupWithSearchQuery.kt 程序时,它会打印以下文档:

Document{{name=Elizabeth Ray, email=arroyocolton@gmail.com, active=true, accounts=[371138, 324287, 276528, 332179, 422649, 387979], purchases=[Document{{account_id=422649, limit=10000, products=[CurrencyService, InvestmentStock]}}, Document{{account_id=324287, limit=10000, products=[Commodity, CurrencyService, Derivatives, InvestmentStock]}}, Document{{account_id=332179, limit=10000, products=[Commodity, CurrencyService, InvestmentFund, Brokerage, InvestmentStock]}}]}}
Document{{name=Lindsay Cowan, email=cooperalexis@hotmail.com, accounts=[116508], purchases=[]}}
Document{{name=Katherine David, email=timothy78@hotmail.com, accounts=[462501, 228290, 968786, 515844, 377292], purchases=[Document{{account_id=228290, limit=10000, products=[CurrencyService, InvestmentStock, InvestmentFund, Brokerage]}}, Document{{account_id=515844, limit=10000, products=[Commodity, CurrencyService, InvestmentFund, Brokerage, InvestmentStock]}}]}}
Document{{name=Leslie Martinez, email=tcrawford@gmail.com, accounts=[170945, 951849], purchases=[]}}
Document{{name=Brad Cardenas, email=dustin37@yahoo.com, accounts=[721914, 817222, 973067, 260799, 87389], purchases=[Document{{account_id=87389, limit=10000, products=[CurrencyService, InvestmentStock]}}, Document{{account_id=260799, limit=10000, products=[Brokerage, InvestmentStock, Commodity, CurrencyService]}}]}}
1
2

以下查询使用以下阶段:

  • $lookup 以执行以下操作:

    • 根据客户的账户 ID 连接 sample_analytics 数据库中的 customersaccounts 集合,并在名为 purchases 的数组字段中返回 accounts 集合中的匹配文档。

    • 使用子管道中的 $search 阶段搜索 must 已购买 CurrencyServiceInvestmentStock 的客户帐户,并优先选择介于 500010000 之间的订单限制。

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

  • $project 阶段以排除结果中的指定字段。

1const MongoClient = require("mongodb").MongoClient;
2const assert = require("assert");
3
4const agg = [
5 {
6 '$lookup': {
7 'from': 'accounts',
8 'localField': 'accounts',
9 'foreignField': 'account_id',
10 'as': 'purchases',
11 'pipeline': [
12 {
13 '$search': {
14 'index': 'lookup-with-search-tutorial',
15 'compound': {
16 'must': [
17 {
18 'queryString': {
19 'defaultPath': 'products',
20 'query': 'products: (CurrencyService AND InvestmentStock)'
21 }
22 }
23 ],
24 'should': [
25 {
26 'range': {
27 'path': 'limit',
28 'gte': 5000,
29 'lte': 10000
30 }
31 }
32 ]
33 }
34 }
35 }, {
36 '$project': {
37 '_id': 0
38 }
39 }
40 ]
41 }
42 }, {
43 '$limit': 5
44 }, {
45 '$project': {
46 '_id': 0,
47 'address': 0,
48 'birthdate': 0,
49 'username': 0,
50 'tier_and_details': 0
51 }
52 }
53 ];
54
55MongoClient.connect(
56 "<connection-string>",
57 { useNewUrlParser: true, useUnifiedTopology: true },
58 async function (connectErr, client) {
59 assert.equal(null, connectErr);
60 const coll = client.db("sample_analytics").collection("customers");
61 let cursor = await coll.aggregate(agg);
62 await cursor.forEach((doc) => console.log(doc));
63 client.close();
64 }
65);
3

确保您的连接字符串包含数据库用户的档案。要了解详情,请参阅通过驱动程序连接

4

运行以下命令来查询您的集合:

node lookup-with-search-query.js
{
name: 'Elizabeth Ray',
email: 'arroyocolton@gmail.com',
active: true,
accounts: [ 371138, 324287, 276528, 332179, 422649, 387979 ],
purchases: [
{ account_id: 422649, limit: 10000, products: [Array] },
{ account_id: 324287, limit: 10000, products: [Array] },
{ account_id: 332179, limit: 10000, products: [Array] }
]
}
{
name: 'Lindsay Cowan',
email: 'cooperalexis@hotmail.com',
accounts: [ 116508 ],
purchases: []
}
{
name: 'Katherine David',
email: 'timothy78@hotmail.com',
accounts: [ 462501, 228290, 968786, 515844, 377292 ],
purchases: [
{ account_id: 228290, limit: 10000, products: [Array] },
{ account_id: 515844, limit: 10000, products: [Array] }
]
}
{
name: 'Leslie Martinez',
email: 'tcrawford@gmail.com',
accounts: [ 170945, 951849 ],
purchases: []
}
{
name: 'Brad Cardenas',
email: 'dustin37@yahoo.com',
accounts: [ 721914, 817222, 973067, 260799, 87389 ],
purchases: [
{ account_id: 87389, limit: 10000, products: [Array] },
{ account_id: 260799, limit: 10000, products: [Array] }
]
}
1
2

以下查询使用以下阶段:

  • $lookup 以执行以下操作:

    • 根据客户的账户 ID 连接 sample_analytics 数据库中的 customersaccounts 集合,并在名为 purchases 的数组字段中返回 accounts 集合中的匹配文档。

    • 使用子管道中的 $search 阶段搜索 must 已购买 CurrencyServiceInvestmentStock 的客户帐户,并优先选择介于 500010000 之间的订单限制。

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

  • $project 阶段以排除结果中的指定字段。

1import pymongo
2
3# connect to your Atlas cluster
4client = pymongo.MongoClient('<connection-string>')
5
6# define pipeline
7pipeline = [
8 {
9 '$lookup': {
10 'from': 'accounts',
11 'localField': 'accounts',
12 'foreignField': 'account_id',
13 'as': 'purchases',
14 'pipeline': [
15 {
16 '$search': {
17 'index': 'lookup-with-search-tutorial',
18 'compound': {
19 'must': [
20 {
21 'queryString': {
22 'defaultPath': 'products',
23 'query': 'products: (CurrencyService AND InvestmentStock)'
24 }
25 }
26 ],
27 'should': [
28 {
29 'range': {
30 'path': 'limit',
31 'gte': 5000,
32 'lte': 10000
33 }
34 }
35 ]
36 }
37 }
38 },
39 { '$project': { '_id': 0 } }
40 ]
41 }
42 },
43 { '$limit': 5 },
44 {
45 '$project': {
46 '_id': 0,
47 'address': 0,
48 'birthdate': 0,
49 'username': 0,
50 'tier_and_details': 0
51 }
52 }
53]
54
55# run pipeline
56result = client['sample_analytics']['customers'].aggregate(pipeline)
57
58# print results
59for i in result:
60 print(i)
3

确保您的连接字符串包含数据库用户的档案。要了解详情,请参阅通过驱动程序连接

4
python lookup-with-search-query.py
{'name': 'Elizabeth Ray', 'email': 'arroyocolton@gmail.com', 'active': True, 'accounts': [371138, 324287, 276528, 332179, 422649, 387979], 'purchases': [{'account_id': 422649, 'limit': 10000, 'products': ['CurrencyService', 'InvestmentStock']}, {'account_id': 324287, 'limit': 10000, 'products': ['Commodity', 'CurrencyService', 'Derivatives', 'InvestmentStock']}, {'account_id': 332179, 'limit': 10000, 'products': ['Commodity', 'CurrencyService', 'InvestmentFund', 'Brokerage', 'InvestmentStock']}]}
{'name': 'Lindsay Cowan', 'email': 'cooperalexis@hotmail.com', 'accounts': [116508], 'purchases': []}
{'name': 'Katherine David', 'email': 'timothy78@hotmail.com', 'accounts': [462501, 228290, 968786, 515844, 377292], 'purchases': [{'account_id': 228290, 'limit': 10000, 'products': ['CurrencyService', 'InvestmentStock', 'InvestmentFund', 'Brokerage']}, {'account_id': 515844, 'limit': 10000, 'products': ['Commodity', 'CurrencyService', 'InvestmentFund', 'Brokerage', 'InvestmentStock']}]}
{'name': 'Leslie Martinez', 'email': 'tcrawford@gmail.com', 'accounts': [170945, 951849], 'purchases': []}
{'name': 'Brad Cardenas', 'email': 'dustin37@yahoo.com', 'accounts': [721914, 817222, 973067, 260799, 87389], 'purchases': [{'account_id': 87389, 'limit': 10000, 'products': ['CurrencyService', 'InvestmentStock']}, {'account_id': 260799, 'limit': 10000, 'products': ['Brokerage', 'InvestmentStock', 'Commodity', 'CurrencyService']}]}

从 v6.0 开始,MongoDB$unionWith 聚合阶段支持$search $unionWithpipeline选项内的 { 。使用$unionWith ,您可以将同一数据库中多个集合的$search结果合并到结果集中。

警告

如果集合没有分布在多个分片上,在子管道中使用 $unionWith$search 的查询在从副本集升级到运行 MongoDB v7.0 的分片集群时可能会失败。为了解决这个问题,请在您的集群上部署多个分片,并对集合进行分片,以便多个数据块可以分布在多个分片上。

本教程演示针对 sample_training 数据库中的 companiesinspections 集合,如何运行带有 $search$unionWith 查询。本教程将引导您完成以下步骤:

  1. sample_training 数据库中的 companiesinspections 集合上创建默认的 Atlas Search 索引。

  2. 使用 $search 运行 $unionWith 查询,以合并 companiesinspections 集合中名称包含 mobile 的公司。

注意

要使用$unionWith 运行$search 查询,您的集群必须运行MongoDB v6.0 或更高版本。要升级MongoDB版本,请参阅升级集群的主要MongoDB版本。

在本部分中,您将在sample_training数据库中companiescollection的所有字段上创建一个名为default的 Atlas Search 搜索索引。您将在sample_training数据库的inspectionscollection中的所有字段上创建另一个名为default的 Atlas Search 搜索索引。您必须为每个collection执行以下步骤。

1

警告

导航改进正在进行中

我们目前正在逐步推出改进的全新导航体验。如果以下步骤与您在 Atlas UI 中的视图不符,请参阅预览文档

  1. 如果尚未显示,请从导航栏上的 Organizations 菜单中选择包含所需项目的组织。

  2. 如果尚未显示,请从导航栏的Projects菜单中选择所需的项目。

  3. 如果尚未出现,请单击侧边栏中的 Clusters(集群)。

    会显示集群页面。

2

您可以从侧边栏、 Data Explorer 或集群详细信息页面转到 Atlas Search 页面。

  1. 在侧边栏中,单击 Services 标题下的 Atlas Search

    如果没有集群,则请单击 Create cluster 来创建一个。要了解更多信息,请参阅创建集群

  2. 如果您的项目有多个集群,请从 Select cluster 下拉列表中选择要使用的集群,然后单击 Go to Atlas Search

    将显示 Atlas Search 页面。

  1. 单击集群的对应 Browse Collections 按钮。

  2. 展开数据库并选择集合。

  3. 单击该集合的 Search Indexes 标签页。

    将显示 Atlas Search 页面。

  1. 单击集群的名称。

  2. 单击 Atlas Search 标签页。

    将显示 Atlas Search 页面。

3
4

在页面上进行以下选择,然后单击 Next

Search Type

选择 Atlas Search 索引类型。

Index Name and Data Source

指定以下信息:

  • Index Name: default

  • Database and Collection:

    • sample_training database

    • companiesinspections 集合

Configuration Method

For a guided experience, select Visual Editor.

To edit the raw index definition, select JSON Editor.

注意

您的 Atlas Search 索引默认名为 default。如果保留此名称,则对于任何未在其操作符中指定不同 index选项的 Atlas Search 查询,您的搜索索引将成为默认搜索索引。如果您要创建多个索引,我们建议您在所有索引中保持一致且具有描述性的命名规则。

5

以下索引定义对集合中的支持类型字段动态创建索引。您可以使用 Atlas Search Visual Editor 或 Atlas Search JSON Editor 在 Atlas 用户界面中创建索引。

查看collection的"default"索引定义。

  1. 查看索引定义。

    您的索引定义应类似于以下示例:

    {
    "mappings": {
    "dynamic": true
    }
    }
6
7

此时将显示一个模态窗口,让您知道索引正在构建中。单击 Close 按钮。

8

构建索引大约需要一分钟时间。在构建时,Status 列显示 Build in Progress。构建完成后,Status 列显示 Active

在本部分中,您将连接到 Atlas 集群,并针对sample_training数据库中的索引集合运行样本查询。

1

在终端窗口中打开mongosh并连接到集群。 有关连接的详细说明,请参阅通过mongosh连接。

2

mongosh 提示符下运行以下命令:

use sample_training
switched to db sample_training
3

以下查询分别在companiesinspectionscollection中搜索namebusiness_name字段中的术语mobile

此查询使用以下阶段:

  • $search可搜索名称中包含mobile的公司。

  • $unionWith 以执行以下操作:

    • 使用子管道中的$search阶段搜索名称中包含mobile的公司的检查。

    • companies中的文档和inspectionscollection中的文档执行并集。

  • $set阶段添加一个名为source的新字段,用于标识输出文档的集合。

    • $limit 阶段将输出限制为每个集合的 3 个结果。

    • $project 阶段到:

      • 在结果中仅包含指定字段。

      • 添加名为 score 的字段。

db.companies.aggregate([
{
"$search": {
"text": {
"query": "Mobile",
"path": "name"
}
}
}, {
"$project": {
"score": {
"$meta": "searchScore"
},
"_id": 0,
"number_of_employees": 1,
"founded_year": 1,
"name": 1
}
}, {
"$set": {
"source": "companies"
}
}, {
"$limit": 3
}, {
"$unionWith": {
"coll": "inspections",
"pipeline": [
{
"$search": {
"text": {
"query": "Mobile",
"path": "business_name"
}
}
}, {
"$set": {
"source": "inspections"
}
}, {
"$project": {
"score": {
"$meta": "searchScore"
},
"source": 1,
"_id": 0,
"business_name": 1,
"address": 1
}
}, {
"$limit": 3
}, {
"$sort": {
"score": -1
}
}
]
}
}
])
[
{
name: 'XLR8 Mobile',
number_of_employees: 21,
founded_year: 2006,
score: 2.0815043449401855,
source: 'companies'
},
{
name: 'Pulse Mobile',
number_of_employees: null,
founded_year: null,
score: 2.0815043449401855,
source: 'companies'
},
{
name: 'T-Mobile',
number_of_employees: null,
founded_year: null,
score: 2.0815043449401855,
source: 'companies'
},
{
business_name: 'T. MOBILE',
address: { city: 'BROOKLYN', zip: 11209, street: '86TH ST', number: 440 },
score: 2.900916337966919,
source: 'inspections'
},
{
business_name: 'BOOST MOBILE',
address: { city: 'BRONX', zip: 10458, street: 'E FORDHAM RD', number: 261 },
score: 2.900916337966919,
source: 'inspections'
},
{
business_name: 'SPRING MOBILE',
address: {
city: 'SOUTH RICHMOND HILL',
zip: 11419,
street: 'LIBERTY AVE',
number: 12207
},
score: 2.900916337966919,
source: 'inspections'
}
]

此查询使用以下阶段:

  • $search可搜索名称中包含mobile的公司。

  • $project 阶段到:

    • 在结果中仅包含指定字段。

    • 添加名为 score 的字段。

  • $addFields 阶段添加以下新字段:

    • 一个名为 source 的新字段,用于标识输出文档的集合。

    • 字段名称 source_count,显示输出文档的计数。

  • $unionWith 以执行以下操作:

    • 使用子管道中的$search阶段搜索名称中包含mobile的公司的检查。

    • companies中的文档和inspectionscollection中的文档执行并集。

  • $project 阶段到:

    • 在结果中仅包含指定字段。

    • 添加名为 score 的字段。

  • $limit 阶段将输出限制为每个集合的 3 个结果。

  • $set 阶段添加以下新字段:

    • 一个名为 source 的新字段,用于标识输出文档的集合。

    • 一个名为 source_count 的新字段,显示输出文档的计数。

db.companies.aggregate([
{
"$search": {
"text": {
"query": "mobile",
"path": "name",
"score": {
"boost": {
"value": 1.6
}
}
}
}
}, {
"$project": {
"score": {
"$meta": "searchScore"
},
"_id": 0,
"number_of_employees": 1,
"founded_year": 1,
"name": 1
}
}, {
"$addFields": {
"source": "companies",
"source_count": "$$SEARCH_META.count.lowerBound"
}
}, {
"$limit": 3
}, {
"$unionWith": {
"coll": "inspections",
"pipeline": [
{
"$search": {
"text": {
"query": "mobile",
"path": "business_name"
}
}
}, {
"$project": {
"score": {
"$meta": "searchScore"
},
"business_name": 1,
"address": 1,
"_id": 0
}
}, {
"$limit": 3
}, {
"$set": {
"source": "inspections",
"source_count": "$$SEARCH_META.count.lowerBound"
}
}, {
"$sort": {
"score": -1
}
}
]
}
}, {
"$facet": {
"allDocs": [],
"totalCount": [
{
"$group": {
"_id": "$source",
"firstCount": {
"$first": "$source_count"
}
}
}, {
"$project": {
"totalCount": {
"$sum": "$firstCount"
}
}
}
]
}
}
])
[
{
allDocs: [
{
name: 'XLR8 Mobile',
number_of_employees: 21,
founded_year: 2006,
score: 3.33040714263916,
source: 'companies',
source_count: Long("52")
},
{
name: 'Pulse Mobile',
number_of_employees: null,
founded_year: null,
score: 3.33040714263916,
source: 'companies',
source_count: Long("52")
},
{
name: 'T-Mobile',
number_of_employees: null,
founded_year: null,
score: 3.33040714263916,
source: 'companies',
source_count: Long("52")
},
{
business_name: 'T. MOBILE',
address: {
city: 'BROOKLYN',
zip: 11209,
street: '86TH ST',
number: 440
},
score: 2.900916337966919,
source: 'inspections',
source_count: Long("456")
},
{
business_name: 'BOOST MOBILE',
address: {
city: 'BRONX',
zip: 10458,
street: 'E FORDHAM RD',
number: 261
},
score: 2.900916337966919,
source: 'inspections',
source_count: Long("456")
},
{
business_name: 'SPRING MOBILE',
address: {
city: 'SOUTH RICHMOND HILL',
zip: 11419,
street: 'LIBERTY AVE',
number: 12207
},
score: 2.900916337966919,
source: 'inspections',
source_count: Long("456")
}
],
totalCount: [
{ _id: 'companies', totalCount: Long("52") },
{ _id: 'inspections', totalCount: Long("456") }
]
}
]
1

打开 MongoDB Compass 并连接到您的集群。有关连接的详细说明,请参阅通过 Compass 连接。

2

Database 屏幕上,依次单击 sample_training 数据库和 companies 集合。

3

以下查询分别在companiesinspectionscollection中搜索namebusiness_name字段中的术语mobile

若要在 MongoDB Compass 中运行此查询:

  1. 单击 Aggregations 标签页。

  2. 单击 Select...,然后从下拉菜单中选择阶段并为该阶段添加查询,以配置以下每个管道阶段。单击 Add Stage 以添加其他阶段。

    此查询使用以下阶段:

    • $search可搜索名称中包含mobile的公司。

    • $unionWith 以执行以下操作:

      • 使用子管道中的$search阶段搜索名称中包含mobile的公司的检查。

      • companies中的文档和inspectionscollection中的文档执行并集。

    • $set阶段添加一个名为source的新字段,用于标识输出文档的集合。

      • $limit 阶段将输出限制为每个集合的 3 个结果。

      • $project 阶段到:

        • 在结果中仅包含指定字段。

        • 添加名为 score 的字段。

    管道阶段
    查询

    $search

    {
    "text": {
    "query": "Mobile",
    "path": "name"
    }
    }

    $project

    {
    "score": {
    "$meta": "searchScore",
    },
    "_id": 0,
    "number_of_employees": 1,
    "founded_year": 1,
    "name": 1
    }

    $set

    {
    "source": "companies"
    }

    $limit

    3

    $unionWith

    {
    "coll": "inspections",
    "pipeline": [
    {
    "$search": {
    "text": {
    "query": "Mobile",
    "path": "business_name",
    }
    }
    },
    {
    "$set": {
    "source": "inspections",
    }
    },
    {
    "$project": {
    "score": {
    "$meta": "searchScore"
    },
    "source": 1,
    "_id": 0,
    "business_name": 1,
    "address": 1
    }
    },
    {
    "$limit": 3
    },
    {
    "$sort": {
    "score": -1
    }
    }
    ]
    }

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

    name: "XLR8 Mobile"
    number_of_employees: 21
    founded_year: 2006
    score: 2.0815043449401855
    source: "companies"
    name: "Pulse Mobile"
    number_of_employees: null
    founded_year: null
    score: 2.0815043449401855
    source: "companies"
    name: "T-Mobile"
    number_of_employees: null
    founded_year: null
    score: 2.0815043449401855
    source: "companies"
    business_name: "T. MOBILE"
    address: Object
    source: "inspections"
    score: 2.900916337966919
    business_name: "BOOST MOBILE"
    address: Object
    source: "inspections"
    score: 2.900916337966919
    business_name: "SPRING MOBILE"
    address: Object
    source: "inspections"
    score: 2.900916337966919

    此查询使用以下阶段:

    • $search可搜索名称中包含mobile的公司。

    • $project 阶段到:

      • 在结果中仅包含指定字段。

      • 添加名为 score 的字段。

    • $addFields 阶段添加以下新字段:

      • 一个名为 source 的新字段,用于标识输出文档的集合。

      • 字段名称 source_count,显示输出文档的计数。

    • $unionWith 以执行以下操作:

      • 使用子管道中的$search阶段搜索名称中包含mobile的公司的检查。

      • companies中的文档和inspectionscollection中的文档执行并集。

    • $project 阶段到:

      • 在结果中仅包含指定字段。

      • 添加名为 score 的字段。

    • $limit 阶段将输出限制为每个集合的 3 个结果。

    • $set 阶段添加以下新字段:

      • 一个名为 source 的新字段,用于标识输出文档的集合。

      • 一个名为 source_count 的新字段,显示输出文档的计数。

    管道阶段
    查询

    $search

    {
    text: {
    query: "mobile",
    path: "name",
    score: {
    boost: {
    value: 1.6
    }
    }
    }
    }

    $project

    {
    "score": {
    "$meta": "searchScore",
    },
    "_id": 0,
    "number_of_employees": 1,
    "founded_year": 1,
    "name": 1
    }

    $addFields

    {
    source: "companies",
    source_count: "$$SEARCH_META.count.lowerBound"
    }

    $limit

    3

    $unionWith

    {
    coll: "inspections",
    pipeline: [
    {
    $search: {
    text: {
    query: "mobile",
    path: "business_name"
    }
    }
    },
    {
    $project: {
    score: {
    $meta: "searchScore"
    },
    business_name: 1,
    address: 1,
    _id: 0
    }
    },
    {
    $limit: 3,
    },
    {
    $set: {
    source: "inspections",
    source_count: "$$SEARCH_META.count.lowerBound"
    }
    },
    {
    $sort: {
    score: -1
    }
    }
    ]
    }

    $facet

    {
    allDocs: [],
    totalCount: [
    {
    $group: {
    _id: "$source",
    firstCount: { $first: "$source_count" }
    }
    },
    {
    $project: {
    totalCount: {
    $sum: "$firstCount"
    }
    }
    }
    ]
    }

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

    allDocs: Array (6)
    0: Object
    name: "XLR8 Mobile"
    number_of_employees: 21
    founded_year: 2006
    score: 3.33040714263916
    source: "companies"
    source_count: 52
    1: Object
    name: "Pulse Mobile"
    number_of_employees: null
    founded_year: null
    score: 3.33040714263916
    source: "companies"
    source_count: 52
    2: Object
    name: "T-Mobile"
    number_of_employees: null
    founded_year: null
    score: 3.33040714263916
    source: "companies"
    source_count: 52
    3: Object
    business_name: "T. MOBILE"
    address: Object
    score: 2.900916337966919
    source: "inspections"
    source_count: 456
    4: Object
    business_name: "BOOST MOBILE"
    address: Object
    score: 2.900916337966919
    source: "inspections"
    source_count: 456
    5: Object
    business_name: "SPRING MOBILE"
    address: Object
    score: 2.900916337966919
    source: "inspections"
    source_count: 456
    totalCount: Array (2)
    0: Object
    _id: "companies"
    totalCount: 52
    1: Object
    _id: "inspections"
    totalCount: 456
4

对于在结果中返回的文档,MongoDB Compass 可能不会显示该文档对象内的所有字段和数组内的所有值。如要查看所有字段和值,请展开结果中的字段。

1
  1. 创建一个名为 search-with-unionwith 的新目录,并使用 dotnet new 命令初始化项目。

    mkdir search-with-unionwith
    cd search-with-unionwith
    dotnet new console
  2. 将 .NET/C# 驱动程序作为依赖项添加到项目中。

    dotnet add package MongoDB.Driver
2

以下查询分别在companiesinspectionscollection中搜索namebusiness_name字段中的术语mobile

此查询使用以下阶段:

  • $search可搜索名称中包含mobile的公司。

  • $unionWith 以执行以下操作:

    • 使用子管道中的$search阶段搜索名称中包含mobile的公司的检查。

    • companies中的文档和inspectionscollection中的文档执行并集。

  • $set阶段添加一个名为source的新字段,用于标识输出文档的集合。

    • $limit 阶段将输出限制为每个集合的 3 个结果。

    • $project 阶段到:

      • 在结果中仅包含指定字段。

      • 添加名为 score 的字段。

1using MongoDB.Bson;
2using MongoDB.Driver;
3using MongoDB.Driver.Search;
4
5public class Program
6{
7 public static void Main(string[] args)
8 {
9 // connect to your Atlas cluster
10 string connectionString = "<connection-string>";
11 var client = new MongoClient(connectionString);
12
13 // define namespace
14 var database = client.GetDatabase("sample_training");
15 var collection = database.GetCollection<BsonDocument>("companies");
16
17 // define pipeline stage
18 var searchStage1 = new BsonDocument("$search", new BsonDocument{{ "text", new BsonDocument
19 {{ "query", "Mobile" },{ "path", "name" }}
20 }});
21 var projectStage1 = new BsonDocument("$project", new BsonDocument{
22 { "score", new BsonDocument("$meta", "searchScore") },
23 { "_id", 0 },{ "number_of_employees", 1 },{ "founded_year", 1 },{ "name", 1 }
24 });
25 var setStage1 = new BsonDocument("$set", new BsonDocument{{ "source", "companies" }});
26 var limitStage1 = new BsonDocument("$limit", 3);
27
28 // define subpipeline
29 var searchStage2 = new BsonDocument("$search", new BsonDocument{{ "text", new BsonDocument
30 {{ "query", "Mobile" },{ "path", "business_name" }}
31 }});
32 var setStage2 = new BsonDocument("$set", new BsonDocument{ { "source", "inspections" } });
33 var projectStage2 = new BsonDocument("$project", new BsonDocument{
34 { "score", new BsonDocument("$meta", "searchScore") },
35 { "source", 1 }, { "_id", 0 }, { "business_name", 1 }, { "address", 1 }
36 });
37 var limitStage2 = new BsonDocument("$limit", 3);
38 var sortStage2 = new BsonDocument("$sort", new BsonDocument{{ "score", -1 }});
39 var unionWithPipeline = new List<BsonDocument>{searchStage2, setStage2, projectStage2, limitStage2, sortStage2};
40 var unionWithStage = new BsonDocument("$unionWith", new BsonDocument
41 {
42 { "coll", "inspections" },
43 { "pipeline", new BsonArray(unionWithPipeline) }
44 });
45 var aggregationPipeline = new List<BsonDocument> {searchStage1, projectStage1, setStage1, limitStage1,unionWithStage};
46
47 // run pipeline
48 var result = collection.Aggregate<BsonDocument>(aggregationPipeline).ToList();
49
50 //print results
51 foreach (var document in result)
52 {
53 Console.WriteLine(document);
54 }
55 }
56}

此查询使用以下阶段:

  • $search可搜索名称中包含mobile的公司。

  • $project 阶段到:

    • 在结果中仅包含指定字段。

    • 添加名为 score 的字段。

  • $addFields 阶段添加以下新字段:

    • 一个名为 source 的新字段,用于标识输出文档的集合。

    • 字段名称 source_count,显示输出文档的计数。

  • $unionWith 以执行以下操作:

    • 使用子管道中的$search阶段搜索名称中包含mobile的公司的检查。

    • companies中的文档和inspectionscollection中的文档执行并集。

  • $project 阶段到:

    • 在结果中仅包含指定字段。

    • 添加名为 score 的字段。

  • $limit 阶段将输出限制为每个集合的 3 个结果。

  • $set 阶段添加以下新字段:

    • 一个名为 source 的新字段,用于标识输出文档的集合。

    • 一个名为 source_count 的新字段,显示输出文档的计数。

1using MongoDB.Bson;
2using MongoDB.Driver;
3
4public class Program
5{
6 public static void Main(string[] args)
7 {
8 // connect to your Atlas cluster
9 var client = new MongoClient("<connection-string>");
10
11 // define namespace
12 var database = client.GetDatabase("sample_training");
13 var collection = database.GetCollection<BsonDocument>("companies");
14
15 // define pipeline
16 var pipeline = new BsonDocument[]
17 {
18 new BsonDocument("$search", new BsonDocument{
19 { "text", new BsonDocument{
20 { "query", "mobile" }, { "path", "name" },
21 { "score", new BsonDocument{
22 { "boost", new BsonDocument{ { "value", 1.6 } }}
23 }}
24 }}
25 }),
26 new BsonDocument("$project", new BsonDocument{
27 { "score", new BsonDocument("$meta", "searchScore") },
28 { "_id", 0 },
29 { "number_of_employees", 1 }, { "founded_year", 1 }, { "name", 1 }
30 }),
31 new BsonDocument("$addFields", new BsonDocument{
32 { "source", "companies" },
33 { "source_count", "$$SEARCH_META.count.lowerBound" }
34 }),
35 new BsonDocument("$limit", 3),
36 new BsonDocument("$unionWith", new BsonDocument{
37 { "coll", "inspections" },
38 { "pipeline", new BsonArray{
39 new BsonDocument("$search", new BsonDocument{
40 { "text", new BsonDocument{
41 { "query", "mobile" },
42 { "path", "business_name" }
43 }}
44 }),
45 new BsonDocument("$project", new BsonDocument{
46 { "score", new BsonDocument("$meta", "searchScore") },
47 { "business_name", 1 }, { "address", 1 }, { "_id", 0 }
48 }),
49 new BsonDocument("$limit", 3),
50 new BsonDocument("$set", new BsonDocument{
51 { "source", "inspections" },
52 { "source_count", "$$SEARCH_META.count.lowerBound" }
53 }),
54 new BsonDocument("$sort", new BsonDocument{
55 { "score", -1 }
56 })
57 }}
58 }),
59 new BsonDocument("$facet", new BsonDocument{
60 { "allDocs", new BsonArray() },
61 { "totalCount", new BsonArray{
62 new BsonDocument("$group", new BsonDocument{
63 { "_id", "$source" },
64 { "firstCount", new BsonDocument("$first", "$source_count") }
65 }),
66 new BsonDocument("$project", new BsonDocument{
67 { "totalCount", new BsonDocument("$sum", "$firstCount") }
68 })
69 }}
70 })
71 };
72
73 // run pipeline
74 var result = collection.Aggregate<BsonDocument>(pipeline).ToList();
75
76 //print results
77 foreach (var document in result)
78 {
79 Console.WriteLine(document);
80 }
81 }
82}
3

确保您的连接字符串包含数据库用户的档案。要了解详情,请参阅通过驱动程序连接

4
dotnet run search-with-unionwith.csproj
{ "name" : "XLR8 Mobile", "number_of_employees" : 21, "founded_year" : 2006, "score" : 2.0815043449401855, "source" : "companies" }
{ "name" : "Pulse Mobile", "number_of_employees" : null, "founded_year" : null, "score" : 2.0815043449401855, "source" : "companies" }
{ "name" : "T-Mobile", "number_of_employees" : null, "founded_year" : null, "score" : 2.0815043449401855, "source" : "companies" }
{ "business_name" : "T. MOBILE", "address" : { "city" : "BROOKLYN", "zip" : 11209, "street" : "86TH ST", "number" : 440 }, "source" : "inspections", "score" : 2.9009163379669189 }
{ "business_name" : "BOOST MOBILE", "address" : { "city" : "BRONX", "zip" : 10458, "street" : "E FORDHAM RD", "number" : 261 }, "source" : "inspections", "score" : 2.9009163379669189 }
{ "business_name" : "SPRING MOBILE", "address" : { "city" : "SOUTH RICHMOND HILL", "zip" : 11419, "street" : "LIBERTY AVE", "number" : 12207 }, "source" : "inspections", "score" : 2.9009163379669189 }
dotnet run search-with-unionwith.csproj
{
"allDocs" : [
{ "name" : "XLR8 Mobile", "number_of_employees" : 21, "founded_year" : 2006, "score" : 3.3304071426391602, "source" : "companies", "source_count" : NumberLong(52) },
{ "name" : "Pulse Mobile", "number_of_employees" : null, "founded_year" : null, "score" : 3.3304071426391602, "source" : "companies", "source_count" : NumberLong(52) },
{ "name" : "T-Mobile", "number_of_employees" : null, "founded_year" : null, "score" : 3.3304071426391602, "source" : "companies", "source_count" : NumberLong(52) },
{ "business_name" : "T. MOBILE", "address" : { "city" : "BROOKLYN", "zip" : 11209, "street" : "86TH ST", "number" : 440 }, "score" : 2.9009163379669189, "source" : "inspections", "source_count" : NumberLong(456) },
{ "business_name" : "BOOST MOBILE", "address" : { "city" : "BRONX", "zip" : 10458, "street" : "E FORDHAM RD", "number" : 261 }, "score" : 2.9009163379669189, "source" : "inspections", "source_count" : NumberLong(456) },
{ "business_name" : "SPRING MOBILE", "address" : { "city" : "SOUTH RICHMOND HILL", "zip" : 11419, "street" : "LIBERTY AVE", "number" : 12207 }, "score" : 2.9009163379669189, "source" : "inspections", "source_count" : NumberLong(456) }
],
"totalCount" : [
{ "_id" : "companies", "totalCount" : NumberLong(52) },
{ "_id" : "inspections", "totalCount" : NumberLong(456) }
]
}
1
2

以下查询分别在companiesinspectionscollection中搜索namebusiness_name字段中的术语mobile

此查询使用以下阶段:

  • $search可搜索名称中包含mobile的公司。

  • $unionWith 以执行以下操作:

    • 使用子管道中的$search阶段搜索名称中包含mobile的公司的检查。

    • companies中的文档和inspectionscollection中的文档执行并集。

  • $set阶段添加一个名为source的新字段,用于标识输出文档的集合。

    • $limit 阶段将输出限制为每个集合的 3 个结果。

    • $project 阶段到:

      • 在结果中仅包含指定字段。

      • 添加名为 score 的字段。

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 the Atlas cluster and set a maximum operation time
15 ctx := context.Background()
16 opts := options.Client().
17 SetTimeout(5 * time.Second).
18 ApplyURI("<connection-string>")
19
20 client, err := mongo.Connect(opts)
21 if err != nil {
22 panic(err)
23 }
24 defer client.Disconnect(ctx)
25
26 // set namespace
27 collection := client.Database("sample_training").Collection("companies")
28 // define pipeline
29 searchStage := bson.D{{"$search", bson.D{
30 {"text", bson.D{
31 {"query", "Mobile"}, {"path", "name"},
32 }},
33 }}}
34 projectStage := bson.D{{"$project", bson.D{
35 {"score", bson.D{{"$meta", "searchScore"}}},
36 {"_id", 0},
37 {"number_of_employees", 1},
38 {"founded_year", 1},
39 {"name", 1},
40 }}}
41 setStage := bson.D{{"$set", bson.D{{"source", "companies"}}}}
42 limitStage := bson.D{{"$limit", 5}}
43 unionWithStage := bson.D{{"$unionWith", bson.D{
44 {"coll", "inspections"},
45 {"pipeline", bson.A{
46 bson.D{{"$search", bson.D{
47 {"text", bson.D{
48 {"query", "Mobile"}, {"path", "business_name"},
49 }},
50 }}},
51 bson.D{{"$set", bson.D{{"source", "inspections"}}}},
52 bson.D{{"$project", bson.D{
53 {"score", bson.D{{"$meta", "searchScore"}}},
54 {"source", 1},
55 {"_id", 0},
56 {"business_name", 1},
57 {"address", 1},
58 }}},
59 bson.D{{"$limit", 3}},
60 bson.D{{"$sort", bson.D{{"score", -1}}}},
61 }},
62 }}}
63 // run pipeline
64 cursor, err := collection.Aggregate(ctx, mongo.Pipeline{searchStage, projectStage, setStage, limitStage, unionWithStage})
65 if err != nil {
66 panic(err)
67 }
68 // print results
69 var results []bson.D
70 if err = cursor.All(context.TODO(), &results); err != nil {
71 panic(err)
72 }
73 for _, result := range results {
74 fmt.Println(result)
75 }
76}

此查询使用以下阶段:

  • $search可搜索名称中包含mobile的公司。

  • $project 阶段到:

    • 在结果中仅包含指定字段。

    • 添加名为 score 的字段。

  • $addFields 阶段添加以下新字段:

    • 一个名为 source 的新字段,用于标识输出文档的集合。

    • 字段名称 source_count,显示输出文档的计数。

  • $unionWith 以执行以下操作:

    • 使用子管道中的$search阶段搜索名称中包含mobile的公司的检查。

    • companies中的文档和inspectionscollection中的文档执行并集。

  • $project 阶段到:

    • 在结果中仅包含指定字段。

    • 添加名为 score 的字段。

  • $limit 阶段将输出限制为每个集合的 3 个结果。

  • $set 阶段添加以下新字段:

    • 一个名为 source 的新字段,用于标识输出文档的集合。

    • 一个名为 source_count 的新字段,显示输出文档的计数。

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 the Atlas cluster and set a maximum operation time
15 ctx := context.Background()
16 opts := options.Client().
17 SetTimeout(5 * time.Second).
18 ApplyURI("<connection-string>")
19
20 client, err := mongo.Connect(opts)
21 if err != nil {
22 panic(err)
23 }
24 defer client.Disconnect(ctx)
25 // set namespace
26 collection := client.Database("sample_training").Collection("companies")
27 // define pipeline
28 searchStage := bson.D{{"$search", bson.D{
29 {"text", bson.D{
30 {"query", "Mobile"}, {"path", "name"}, {"score", bson.D{{"boost", bson.D{{"value", 1.6}}}}},
31 }},
32 }}}
33 projectStage := bson.D{{"$project", bson.D{
34 {"score", bson.D{{"$meta", "searchScore"}}},
35 {"_id", 0},
36 {"number_of_employees", 1},
37 {"founded_year", 1},
38 {"name", 1},
39 }}}
40 addFieldsStage := bson.D{{"$set", bson.D{
41 {"source", "companies"},
42 {"source_count", "$$SEARCH_META.count.lowerBound"},
43 }}}
44 limitStage := bson.D{{"$limit", 3}}
45 unionWithStage := bson.D{{"$unionWith", bson.D{
46 {"coll", "inspections"},
47 {"pipeline", bson.A{
48 bson.D{{"$search", bson.D{
49 {"text", bson.D{
50 {"query", "mobile"}, {"path", "business_name"},
51 }},
52 }}},
53 bson.D{{"$project", bson.D{
54 {"score", bson.D{{"$meta", "searchScore"}}},
55 {"business_name", 1},
56 {"address", 1},
57 {"_id", 0},
58 }}},
59 bson.D{{"$limit", 3}},
60 bson.D{{"$set", bson.D{
61 {"source", "inspections"},
62 {"source_count", "$$SEARCH_META.count.lowerBound"},
63 }}},
64 bson.D{{"$sort", bson.D{{"score", -1}}}},
65 }},
66 }}}
67 facetStage := bson.D{{"$facet", bson.D{
68 {"allDocs", bson.A{}},
69 {"totalCount", bson.A{
70 bson.D{
71 {"$group", bson.D{
72 {"_id", "$source"},
73 {"firstCount", bson.D{{"$first", "$source_count"}}},
74 }},
75 },
76 bson.D{{"$project", bson.D{{"totalCount", bson.D{{"$sum", "$firstCount"}}}}}},
77 }},
78 }}}
79 // run pipeline
80 cursor, err := collection.Aggregate(ctx, mongo.Pipeline{searchStage, projectStage, addFieldsStage, limitStage, unionWithStage, facetStage})
81 if err != nil {
82 panic(err)
83 }
84 // print results
85 var results []bson.D
86 if err = cursor.All(context.TODO(), &results); err != nil {
87 panic(err)
88 }
89 for _, result := range results {
90 fmt.Println(result)
91 }
92}
3

确保您的连接字符串包含数据库用户的档案。要了解详情,请参阅通过驱动程序连接

4
go run search-with-unionwith-query.go
[{name XLR8 Mobile} {number_of_employees 21} {founded_year 2006} {score 3.33040714263916} {source companies} {source_count 52}]
[{name Pulse Mobile} {number_of_employees <nil>} {founded_year <nil>} {score 3.33040714263916} {source companies} {source_count 52}]
[{name T-Mobile} {number_of_employees <nil>} {founded_year <nil>} {score 3.33040714263916} {source companies} {source_count 52}]
[{business_name T. MOBILE} {address [{city BROOKLYN} {zip 11209} {street 86TH ST} {number 440}]} {score 2.900916337966919} {source inspections} {source_count 456}]
[{business_name BOOST MOBILE} {address [{city BRONX} {zip 10458} {street E FORDHAM RD} {number 261}]} {score 2.900916337966919} {source inspections} {source_count 456}]
[{business_name SPRING MOBILE} {address [{city SOUTH RICHMOND HILL} {zip 11419} {street LIBERTY AVE} {number 12207}]} {score 2.900916337966919} {source inspections} {source_count 456}]
go run search-with-unionwith-query.go
[
{allDocs [
[{name XLR8 Mobile} {number_of_employees 21} {founded_year 2006} {score 3.33040714263916} {source companies} {source_count 52}]
[{name Pulse Mobile} {number_of_employees <nil>} {founded_year <nil>} {score 3.33040714263916} {source companies} {source_count 52}]
[{name T-Mobile} {number_of_employees <nil>} {founded_year <nil>} {score 3.33040714263916} {source companies} {source_count 52}]
[{business_name T. MOBILE} {address [{city BROOKLYN} {zip 11209} {street 86TH ST} {number 440}]} {score 2.900916337966919} {source inspections} {source_count 456}]
[{business_name BOOST MOBILE} {address [{city BRONX} {zip 10458} {street E FORDHAM RD} {number 261}]} {score 2.900916337966919} {source inspections} {source_count 456}]
[{business_name SPRING MOBILE} {address [{city SOUTH RICHMOND HILL} {zip 11419} {street LIBERTY AVE} {number 12207}]} {score 2.900916337966919} {source inspections} {source_count 456}]
]}
{totalCount [
[{_id inspections} {totalCount 456}]
[{_id companies} {totalCount 52}]
]}
]
1

junit

4.11 或更高版本

mongodb-driver-sync

4.3.0 或更高版本

slf4j-log4j12

1.7.30 或更高版本

2
3

以下查询分别在companiesinspectionscollection中搜索namebusiness_name字段中的术语mobile

此查询使用以下阶段:

  • $search可搜索名称中包含mobile的公司。

  • $unionWith 以执行以下操作:

    • 使用子管道中的$search阶段搜索名称中包含mobile的公司的检查。

    • companies中的文档和inspectionscollection中的文档执行并集。

  • $set阶段添加一个名为source的新字段,用于标识输出文档的集合。

    • $limit 阶段将输出限制为每个集合的 3 个结果。

    • $project 阶段到:

      • 在结果中仅包含指定字段。

      • 添加名为 score 的字段。

1import com.mongodb.client.MongoClients;
2import com.mongodb.client.MongoClient;
3import com.mongodb.client.MongoDatabase;
4import org.bson.Document;
5import java.util.ArrayList;
6import java.util.Arrays;
7import java.util.List;
8
9public class SearchWithUnionwith {
10 public static void main(String[] args) {
11 // connect to Atlas cluster
12 try (MongoClient mongoClient = MongoClients.create("<connection-string>")) {
13 // get database name
14 MongoDatabase database = mongoClient.getDatabase("sample_training");
15 // define pipeline
16 List<Document> pipeline1 = Arrays.asList(
17 new Document("$search", new Document("text",
18 new Document("query", "Mobile")
19 .append("path", "name"))),
20 new Document("$project", new Document("score",
21 new Document("$meta", "searchScore"))
22 .append("_id", 0)
23 .append("number_of_employees", 1)
24 .append("founded_year", 1)
25 .append("name", 1)),
26 new Document("$set", new Document("source", "companies")),
27 new Document("$limit", 3)
28 );
29
30 List<Document> pipeline2 = Arrays.asList(
31 new Document("$search", new Document("text",
32 new Document("query", "Mobile")
33 .append("path", "business_name"))),
34 new Document("$set", new Document("source", "inspections")),
35 new Document("$project", new Document("score",
36 new Document("$meta", "searchScore"))
37 .append("source", 1)
38 .append("_id", 0)
39 .append("business_name", 1)
40 .append("address", 1)),
41 new Document("$limit", 3),
42 new Document("$sort", new Document("score", -1))
43 );
44
45 List<Document> unionWithStage = new ArrayList<>();
46 Document unionWith = new Document("$unionWith", new Document("coll", "inspections")
47 .append("pipeline", pipeline2));
48 unionWithStage.add(unionWith);
49
50 List<Document> finalPipeline = new ArrayList<>(pipeline1);
51 finalPipeline.addAll(unionWithStage);
52 // run pipeline and print results
53 database.getCollection("companies").aggregate(finalPipeline)
54 .forEach(doc -> System.out.println(doc.toJson()));
55 }
56 }
57}

此查询使用以下阶段:

  • $search可搜索名称中包含mobile的公司。

  • $project 阶段到:

    • 在结果中仅包含指定字段。

    • 添加名为 score 的字段。

  • $addFields 阶段添加以下新字段:

    • 一个名为 source 的新字段,用于标识输出文档的集合。

    • 字段名称 source_count,显示输出文档的计数。

  • $unionWith 以执行以下操作:

    • 使用子管道中的$search阶段搜索名称中包含mobile的公司的检查。

    • companies中的文档和inspectionscollection中的文档执行并集。

  • $project 阶段到:

    • 在结果中仅包含指定字段。

    • 添加名为 score 的字段。

  • $limit 阶段将输出限制为每个集合的 3 个结果。

  • $set 阶段添加以下新字段:

    • 一个名为 source 的新字段,用于标识输出文档的集合。

    • 一个名为 source_count 的新字段,显示输出文档的计数。

1import com.mongodb.client.MongoClients;
2import com.mongodb.client.MongoCollection;
3import com.mongodb.client.MongoClient;
4import org.bson.Document;
5
6public class SearchWithUnionwith {
7 public static void main(String[] args) {
8 // connect to Atlas cluster
9 try (MongoClient mongoClient = MongoClients.create("<connection-string>")) {
10 // define namespace
11 MongoCollection<Document> collection = mongoClient.getDatabase("sample_training").getCollection("companies");
12 // define pipeline
13 Document searchStage = new Document("$search", new Document("text",
14 new Document("query", "mobile")
15 .append("path", "name")
16 .append("score", new Document("boost", new Document("value", 1.6)))
17 )
18 );
19
20 Document projectStage = new Document("$project", new Document("score", new Document("$meta", "searchScore"))
21 .append("_id", 0)
22 .append("number_of_employees", 1)
23 .append("founded_year", 1)
24 .append("name", 1)
25 );
26
27 Document addFieldsStage = new Document("$addFields", new Document("source", "companies")
28 .append("source_count", "$$SEARCH_META.count.lowerBound")
29 );
30
31 Document limitStage = new Document("$limit", 3);
32
33 Document unionWithStage = new Document("$unionWith", new Document("coll", "inspections")
34 .append("pipeline", java.util.Arrays.asList(
35 new Document("$search", new Document("text",
36 new Document("query", "mobile")
37 .append("path", "business_name")
38 )),
39 new Document("$project", new Document("score", new Document("$meta", "searchScore"))
40 .append("business_name", 1)
41 .append("address", 1)
42 .append("_id", 0)
43 ),
44 new Document("$limit", 3),
45 new Document("$set", new Document("source", "inspections")
46 .append("source_count", "$$SEARCH_META.count.lowerBound")
47 ),
48 new Document("$sort", new Document("score", -1))
49 ))
50 );
51
52 Document facetStage = new Document("$facet", new Document("allDocs", java.util.Arrays.asList())
53 .append("totalCount", java.util.Arrays.asList(
54 new Document("$group", new Document("_id", "$source")
55 .append("firstCount", new Document("$first", "$source_count"))
56 ),
57 new Document("$project", new Document("totalCount",
58 new Document("$sum", "$firstCount")
59 ))
60 ))
61 );
62 // run pipeline and print results
63 collection.aggregate(java.util.Arrays.asList(
64 searchStage, projectStage, addFieldsStage, limitStage, unionWithStage, facetStage
65 )).forEach(doc -> System.out.println(doc.toJson()));
66 }
67 }
68}

注意

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

package com.mongodb.drivers;
4

确保您的连接字符串包含数据库用户的档案。要了解详情,请参阅通过驱动程序连接

5
javac SearchWithUnionwithQuery.java
java SearchWithUnionwithQuery
{"name": "XLR8 Mobile", "number_of_employees": 21, "founded_year": 2006, "score": 2.0815043449401855, "source": "companies"}
{"name": "Pulse Mobile", "number_of_employees": null, "founded_year": null, "score": 2.0815043449401855, "source": "companies"}
{"name": "T-Mobile", "number_of_employees": null, "founded_year": null, "score": 2.0815043449401855, "source": "companies"}
{"business_name": "T. MOBILE", "address": {"city": "BROOKLYN", "zip": 11209, "street": "86TH ST", "number": 440}, "source": "inspections", "score": 2.900916337966919}
{"business_name": "BOOST MOBILE", "address": {"city": "BRONX", "zip": 10458, "street": "E FORDHAM RD", "number": 261}, "source": "inspections", "score": 2.900916337966919}
{"business_name": "SPRING MOBILE", "address": {"city": "SOUTH RICHMOND HILL", "zip": 11419, "street": "LIBERTY AVE", "number": 12207}, "source": "inspections", "score": 2.900916337966919}
javac SearchWithUnionwithQuery.java
java SearchWithUnionwithQuery
{
"allDocs": [
{"name": "XLR8 Mobile", "number_of_employees": 21, "founded_year": 2006, "score": 3.33040714263916, "source": "companies", "source_count": 52},
{"name": "Pulse Mobile", "number_of_employees": null, "founded_year": null, "score": 3.33040714263916, "source": "companies", "source_count": 52},
{"name": "T-Mobile", "number_of_employees": null, "founded_year": null, "score": 3.33040714263916, "source": "companies", "source_count": 52},
{"business_name": "T. MOBILE", "address": {"city": "BROOKLYN", "zip": 11209, "street": "86TH ST", "number": 440}, "score": 2.900916337966919, "source": "inspections", "source_count": 456},
{"business_name": "BOOST MOBILE", "address": {"city": "BRONX", "zip": 10458, "street": "E FORDHAM RD", "number": 261}, "score": 2.900916337966919, "source": "inspections", "source_count": 456},
{"business_name": "SPRING MOBILE", "address": {"city": "SOUTH RICHMOND HILL", "zip": 11419, "street": "LIBERTY AVE", "number": 12207}, "score": 2.900916337966919, "source": "inspections", "source_count": 456}
],
"totalCount": [
{"_id": "companies", "totalCount": 52},
{"_id": "inspections", "totalCount": 456}
]
}
1

mongodb-driver-kotlin-coroutine

4.10.0 或更高版本

2
3

以下查询分别在companiesinspectionscollection中搜索namebusiness_name字段中的术语mobile

此查询使用以下阶段:

  • $search可搜索名称中包含mobile的公司。

  • $unionWith 以执行以下操作:

    • 使用子管道中的$search阶段搜索名称中包含mobile的公司的检查。

    • companies中的文档和inspectionscollection中的文档执行并集。

  • $set阶段添加一个名为source的新字段,用于标识输出文档的集合。

    • $limit 阶段将输出限制为每个集合的 3 个结果。

    • $project 阶段到:

      • 在结果中仅包含指定字段。

      • 添加名为 score 的字段。

1import com.mongodb.kotlin.client.coroutine.MongoClient
2import kotlinx.coroutines.runBlocking
3import org.bson.Document
4
5fun main() {
6 // connect to Atlas cluster
7 val uri = "<connection-string>"
8 val mongoClient = MongoClient.create(uri)
9
10 // set namespace
11 val database = mongoClient.getDatabase("sample_training")
12 val collection = database.getCollection<Document>("companies")
13
14 runBlocking {
15 // define pipeline
16 val pipeline1 = listOf(
17 Document("\$search", Document("text",
18 Document("query", "Mobile")
19 .append("path", "name"))), Document("\$project", Document("score",
20 Document("\$meta", "searchScore"))
21 .append("_id", 0)
22 .append("number_of_employees", 1)
23 .append("founded_year", 1)
24 .append("name", 1)), Document("\$set", Document("source", "companies")),
25 Document("\$limit", 3)
26 )
27
28 val pipeline2 = listOf(
29 Document(
30 "\$search", Document(
31 "text",
32 Document("query", "Mobile")
33 .append("path", "business_name")
34 )
35 ),
36 Document("\$set", Document("source", "inspections")),
37 Document(
38 "\$project", Document(
39 "score",
40 Document("\$meta", "searchScore")
41 )
42 .append("source", 1)
43 .append("_id", 0)
44 .append("business_name", 1)
45 .append("address", 1)
46 ),
47 Document("\$limit", 3),
48 Document("\$sort", Document("score", -1))
49 )
50
51 val unionWithStage: MutableList<Document> = ArrayList()
52 val unionWith = Document(
53 "\$unionWith", Document("coll", "inspections")
54 .append("pipeline", pipeline2)
55 )
56 unionWithStage.add(unionWith)
57 val finalPipeline: MutableList<Document> = ArrayList(pipeline1)
58 finalPipeline.addAll(unionWithStage)
59
60 // run pipeline and print results
61 val resultsFlow = collection.aggregate<Document>(finalPipeline)
62 resultsFlow.collect { println(it) }
63
64 }
65 mongoClient.close()
66}

此查询使用以下阶段:

  • $search可搜索名称中包含mobile的公司。

  • $project 阶段到:

    • 在结果中仅包含指定字段。

    • 添加名为 score 的字段。

  • $addFields 阶段添加以下新字段:

    • 一个名为 source 的新字段,用于标识输出文档的集合。

    • 字段名称 source_count,显示输出文档的计数。

  • $unionWith 以执行以下操作:

    • 使用子管道中的$search阶段搜索名称中包含mobile的公司的检查。

    • companies中的文档和inspectionscollection中的文档执行并集。

  • $project 阶段到:

    • 在结果中仅包含指定字段。

    • 添加名为 score 的字段。

  • $limit 阶段将输出限制为每个集合的 3 个结果。

  • $set 阶段添加以下新字段:

    • 一个名为 source 的新字段,用于标识输出文档的集合。

    • 一个名为 source_count 的新字段,显示输出文档的计数。

1import com.mongodb.kotlin.client.coroutine.MongoClient
2import kotlinx.coroutines.runBlocking
3import org.bson.Document
4import java.util.*
5
6fun main() {
7 // connect to Atlas cluster
8 val uri = "<connection-string>"
9 val mongoClient = MongoClient.create(uri)
10
11 // set namespace
12 val database = mongoClient.getDatabase("sample_training")
13 val collection = database.getCollection<Document>("companies")
14
15 runBlocking {
16 // define pipeline stages
17 val searchStage = Document(
18 "\$search", Document(
19 "text",
20 Document("query", "mobile")
21 .append("path", "name")
22 .append("score", Document("boost", Document("value", 1.6)))
23 )
24 )
25
26 val projectStage = Document(
27 "\$project", Document("score", Document("\$meta", "searchScore"))
28 .append("_id", 0)
29 .append("number_of_employees", 1)
30 .append("founded_year", 1)
31 .append("name", 1)
32 )
33
34 val addFieldsStage = Document(
35 "\$addFields", Document("source", "companies")
36 .append("source_count", "$\$SEARCH_META.count.lowerBound")
37 )
38
39 val limitStage = Document("\$limit", 3)
40
41 val unionWithStage = Document(
42 "\$unionWith", Document("coll", "inspections")
43 .append(
44 "pipeline", Arrays.asList(
45 Document(
46 "\$search", Document(
47 "text",
48 Document("query", "mobile")
49 .append("path", "business_name")
50 )
51 ),
52 Document(
53 "\$project", Document("score", Document("\$meta", "searchScore"))
54 .append("business_name", 1)
55 .append("address", 1)
56 .append("_id", 0)
57 ),
58 Document("\$limit", 3),
59 Document(
60 "\$set", Document("source", "inspections")
61 .append("source_count", "$\$SEARCH_META.count.lowerBound")
62 ),
63 Document("\$sort", Document("score", -1))
64 )
65 )
66 )
67
68 val facetStage = Document(
69 "\$facet", Document("allDocs", Arrays.asList<Any>())
70 .append(
71 "totalCount", Arrays.asList(
72 Document(
73 "\$group", Document("_id", "\$source")
74 .append("firstCount", Document("\$first", "\$source_count"))
75 ),
76 Document(
77 "\$project", Document(
78 "totalCount",
79 Document("\$sum", "\$firstCount")
80 )
81 )
82 )
83 )
84 )
85
86 // run pipeline and print results
87 val resultsFlow = collection.aggregate<Document>(
88 listOf(
89 searchStage,
90 projectStage,
91 addFieldsStage,
92 limitStage,
93 unionWithStage,
94 facetStage
95 )
96 )
97 resultsFlow.collect { println(it) }
98
99 }
100 mongoClient.close()
101}
4

确保您的连接字符串包含数据库用户的档案。要了解详情,请参阅通过驱动程序连接

5

当你在 IDE 中运行 SearchWithUnionwithQuery.kt 程序时,它会打印以下文档:

Document{{name=XLR8 Mobile, number_of_employees=21, founded_year=2006, score=2.0815043449401855, source=companies}}
Document{{name=Pulse Mobile, number_of_employees=null, founded_year=null, score=2.0815043449401855, source=companies}}
Document{{name=Mobile Trend, number_of_employees=null, founded_year=2003, score=2.0815043449401855, source=companies}}
Document{{business_name=T-MOBILE, address=Document{{city=BROOKLYN, zip=11229, street=AVENUE U, number=1616}}, source=inspections, score=2.900916337966919}}
Document{{business_name=BOOST MOBILE, address=Document{{city=BRONX, zip=10458, street=E FORDHAM RD, number=261}}, source=inspections, score=2.900916337966919}}
Document{{business_name=SPRING MOBILE, address=Document{{city=SOUTH RICHMOND HILL, zip=11419, street=LIBERTY AVE, number=12207}}, source=inspections, score=2.900916337966919}}

当您在 IDE 中运行 SearchWithUnionwithQuery.kt 程序时,它会打印以下结果:

Document{{allDocs=[Document{{name=XLR8 Mobile,
number_of_employees=21, founded_year=2006,
score=3.33040714263916, source=companies,
source_count=52}}, Document{{name=Pulse Mobile,
number_of_employees=null, founded_year=null,
score=3.33040714263916, source=companies,
source_count=52}}, Document{{name=Mobile Trend,
number_of_employees=null, founded_year=2003,
score=3.33040714263916, source=companies,
source_count=52}}, Document{{business_name=T-MOBILE,
address=Document{{city=BROOKLYN, zip=11229, street=AVENUE
U, number=1616}}, score=2.900916337966919,
source=inspections, source_count=456}},
Document{{business_name=BOOST MOBILE,
address=Document{{city=BRONX, zip=10458, street=E FORDHAM
RD, number=261}}, score=2.900916337966919,
source=inspections, source_count=456}},
Document{{business_name=SPRING MOBILE,
address=Document{{city=SOUTH RICHMOND HILL, zip=11419,
street=LIBERTY AVE, number=12207}},
score=2.900916337966919, source=inspections,
source_count=456}}],
totalCount=[Document{{_id=inspections, totalCount=456}},
Document{{_id=companies, totalCount=52}}]}}
1
2

以下查询分别在companiesinspectionscollection中搜索namebusiness_name字段中的术语mobile

此查询使用以下阶段:

  • $search可搜索名称中包含mobile的公司。

  • $unionWith 以执行以下操作:

    • 使用子管道中的$search阶段搜索名称中包含mobile的公司的检查。

    • companies中的文档和inspectionscollection中的文档执行并集。

  • $set阶段添加一个名为source的新字段,用于标识输出文档的集合。

    • $limit 阶段将输出限制为每个集合的 3 个结果。

    • $project 阶段到:

      • 在结果中仅包含指定字段。

      • 添加名为 score 的字段。

1const MongoClient = require("mongodb").MongoClient;
2const assert = require("assert");
3
4const agg = [
5 {
6 '$search': {
7 'text': { 'query': 'Mobile', 'path': 'name' }
8 }
9 }, {
10 '$project': {
11 'score': { '$meta': 'searchScore' },
12 '_id': 0, 'number_of_employees': 1, 'founded_year': 1, 'name': 1
13 }
14 }, {
15 '$set': { 'source': 'companies' }
16 }, {
17 '$limit': 3
18 }, {
19 '$unionWith': {
20 'coll': 'inspections',
21 'pipeline': [
22 {
23 '$search': {
24 'text': { 'query': 'Mobile', 'path': 'business_name' }
25 }
26 }, {
27 '$set': { 'source': 'inspections' }
28 }, {
29 '$project': {
30 'score': { '$meta': 'searchScore' },
31 'source': 1, '_id': 0, 'business_name': 1, 'address': 1
32 }
33 }, {
34 '$limit': 3
35 }, {
36 '$sort': { 'score': -1 }
37 }
38 ]
39 }
40 }
41 ];
42
43MongoClient.connect(
44 "<connection-string>",
45 { useNewUrlParser: true, useUnifiedTopology: true },
46 async function (connectErr, client) {
47 assert.equal(null, connectErr);
48 const coll = client.db("sample_training").collection("companies");
49 let cursor = await coll.aggregate(agg);
50 await cursor.forEach((doc) => console.log(doc));
51 client.close();
52 }
53);

此查询使用以下阶段:

  • $search可搜索名称中包含mobile的公司。

  • $project 阶段到:

    • 在结果中仅包含指定字段。

    • 添加名为 score 的字段。

  • $addFields 阶段添加以下新字段:

    • 一个名为 source 的新字段,用于标识输出文档的集合。

    • 字段名称 source_count,显示输出文档的计数。

  • $unionWith 以执行以下操作:

    • 使用子管道中的$search阶段搜索名称中包含mobile的公司的检查。

    • companies中的文档和inspectionscollection中的文档执行并集。

  • $project 阶段到:

    • 在结果中仅包含指定字段。

    • 添加名为 score 的字段。

  • $limit 阶段将输出限制为每个集合的 3 个结果。

  • $set 阶段添加以下新字段:

    • 一个名为 source 的新字段,用于标识输出文档的集合。

    • 一个名为 source_count 的新字段,显示输出文档的计数。

1const MongoClient = require("mongodb").MongoClient;
2const assert = require("assert");
3
4const agg = [
5 {'$search': { 'text': {
6 'query': 'mobile',
7 'path': 'name',
8 'score': {
9 'boost': { 'value': 1.6 }
10 }
11 }}},
12 {'$project': {
13 'score': { '$meta': 'searchScore' },
14 '_id': 0,
15 'number_of_employees': 1,
16 'founded_year': 1,
17 'name': 1
18 }},
19 {'$addFields': {
20 'source': 'companies',
21 'source_count': '$$SEARCH_META.count.lowerBound'
22 }},
23 {'$limit': 3},
24 {'$unionWith': {
25 'coll': 'inspections',
26 'pipeline': [
27 {'$search': {
28 'text': { 'query': 'mobile', 'path': 'business_name' }
29 }},
30 {'$project': {
31 'score': { '$meta': 'searchScore' },
32 'business_name': 1,
33 'address': 1,
34 '_id': 0
35 }},
36 {'$limit': 3},
37 {'$set': {
38 'source': 'inspections',
39 'source_count': '$$SEARCH_META.count.lowerBound'
40 }},
41 {'$sort': { 'score': -1 } }
42 ]
43 }},
44 {'$facet': {
45 'allDocs': [],
46 'totalCount': [
47 {'$group': {
48 '_id': '$source',
49 'firstCount': { '$first': '$source_count' }
50 }},
51 {'$project': {
52 'totalCount': { '$sum': '$firstCount' }
53 }}
54 ]
55 }}
56];
57
58MongoClient.connect(
59 "<connection-string>",
60 { useNewUrlParser: true, useUnifiedTopology: true },
61 async function (connectErr, client) {
62 assert.equal(null, connectErr);
63 const coll = client.db("sample_training").collection("companies");
64 let cursor = await coll.aggregate(agg);
65 await cursor.forEach((doc) => console.log(doc));
66 client.close();
67 }
68);
3

确保您的连接字符串包含数据库用户的档案。要了解详情,请参阅通过驱动程序连接

4

运行以下命令来查询您的集合:

node unionwith-with-search-query.js
{
name: 'SoftBank Mobile',
number_of_employees: null,
founded_year: null,
score: 2.0815043449401855,
source: 'companies'
}
{
name: 'Mobile Factory',
number_of_employees: 53,
founded_year: 2001,
score: 2.0815043449401855,
source: 'companies'
}
{
name: 'ZOOZ Mobile',
number_of_employees: 5,
founded_year: 2008,
score: 2.0815043449401855,
source: 'companies'
}
{
business_name: 'T. MOBILE',
address: { city: 'BROOKLYN', zip: 11209, street: '86TH ST', number: 440 },
source: 'inspections',
score: 2.900916337966919
}
{
business_name: 'BOOST MOBILE',
address: { city: 'BRONX', zip: 10458, street: 'E FORDHAM RD', number: 261 },
source: 'inspections',
score: 2.900916337966919
}
{
business_name: 'T-MOBILE',
address: { city: 'BROOKLYN', zip: 11229, street: 'AVENUE U', number: 1616 },
source: 'inspections',
score: 2.900916337966919
}
node unionwith-with-search-query.js
{
allDocs: [
{
name: 'XLR8 Mobile',
number_of_employees: 21,
founded_year: 2006,
score: 3.33040714263916,
source: 'companies',
source_count: 52
},
{
name: 'Pulse Mobile',
number_of_employees: null,
founded_year: null,
score: 3.33040714263916,
source: 'companies',
source_count: 52
},
{
name: 'T-Mobile',
number_of_employees: null,
founded_year: null,
score: 3.33040714263916,
source: 'companies',
source_count: 52
},
{
business_name: 'T. MOBILE',
address: [Object],
score: 2.900916337966919,
source: 'inspections',
source_count: 456
},
{
business_name: 'BOOST MOBILE',
address: [Object],
score: 2.900916337966919,
source: 'inspections',
source_count: 456
},
{
business_name: 'SPRING MOBILE',
address: [Object],
score: 2.900916337966919,
source: 'inspections',
source_count: 456
}
],
totalCount: [
{ _id: 'companies', totalCount: 52 },
{ _id: 'inspections', totalCount: 456 }
]
}
1
2

以下查询分别在companiesinspectionscollection中搜索namebusiness_name字段中的术语mobile

此查询使用以下阶段:

  • $search可搜索名称中包含mobile的公司。

  • $unionWith 以执行以下操作:

    • 使用子管道中的$search阶段搜索名称中包含mobile的公司的检查。

    • companies中的文档和inspectionscollection中的文档执行并集。

  • $set阶段添加一个名为source的新字段,用于标识输出文档的集合。

    • $limit 阶段将输出限制为每个集合的 3 个结果。

    • $project 阶段到:

      • 在结果中仅包含指定字段。

      • 添加名为 score 的字段。

1import pymongo
2import dns
3
4client = pymongo.MongoClient('<connection-string>')
5result = client['sample_training']['companies'].aggregate([
6 {
7 '$search': {
8 'text': { 'query': 'Mobile', 'path': 'name' }
9 }
10 }, {
11 '$project': {
12 'score': { '$meta': 'searchScore' }, '_id': 0, 'number_of_employees': 1, 'founded_year': 1, 'name': 1
13 }
14 }, {
15 '$set': { 'source': 'companies' }
16 }, {
17 '$limit': 3
18 }, {
19 '$unionWith': {
20 'coll': 'inspections',
21 'pipeline': [
22 {
23 '$search': {
24 'text': { 'query': 'Mobile', 'path': 'business_name' }
25 }
26 }, {
27 '$set': { 'source': 'inspections' }
28 }, {
29 '$project': {
30 'score': { '$meta': 'searchScore' }, 'source': 1, '_id': 0, 'business_name': 1, 'address': 1
31 }
32 }, {
33 '$limit': 3
34 }, {
35 '$sort': { 'score': -1 }
36 }
37 ]
38 }
39 }
40])
41
42for i in result:
43 print(i)

此查询使用以下阶段:

  • $search可搜索名称中包含mobile的公司。

  • $project 阶段到:

    • 在结果中仅包含指定字段。

    • 添加名为 score 的字段。

  • $addFields 阶段添加以下新字段:

    • 一个名为 source 的新字段,用于标识输出文档的集合。

    • 字段名称 source_count,显示输出文档的计数。

  • $unionWith 以执行以下操作:

    • 使用子管道中的$search阶段搜索名称中包含mobile的公司的检查。

    • companies中的文档和inspectionscollection中的文档执行并集。

  • $project 阶段到:

    • 在结果中仅包含指定字段。

    • 添加名为 score 的字段。

  • $limit 阶段将输出限制为每个集合的 3 个结果。

  • $set 阶段添加以下新字段:

    • 一个名为 source 的新字段,用于标识输出文档的集合。

    • 一个名为 source_count 的新字段,显示输出文档的计数。

1import pymongo
2import dns
3
4client = pymongo.MongoClient('<connection-string>')
5result = client['sample_training']['companies'].aggregate([
6 {'$search': { 'text': {
7 'query': 'mobile',
8 'path': 'name',
9 'score': { 'boost': { 'value': 1.6 } }
10 }}},
11 {'$project': {
12 'score': { '$meta': 'searchScore' },
13 '_id': 0,
14 'number_of_employees': 1,
15 'founded_year': 1,
16 'name': 1
17 }},
18 {'$addFields': {
19 'source': 'companies',
20 'source_count': '$$SEARCH_META.count.lowerBound'
21 }},
22 {'$limit': 3},
23 {'$unionWith': {
24 'coll': 'inspections',
25 'pipeline': [
26 {'$search': { 'text': {
27 'query': 'mobile',
28 'path': 'business_name'
29 }} },
30 {'$project': {
31 'score': { '$meta': 'searchScore' },
32 'business_name': 1,
33 'address': 1,
34 '_id': 0
35 }},
36 {'$limit': 3},
37 {'$set': {
38 'source': 'inspections',
39 'source_count': '$$SEARCH_META.count.lowerBound'
40 }},
41 {'$sort': { 'score': -1 }}
42 ]
43 }},
44 {'$facet': {
45 'allDocs': [],
46 'totalCount': [
47 {'$group': {
48 '_id': '$source',
49 'firstCount': { '$first': '$source_count' }
50 }},
51 {'$project': {
52 'totalCount': { '$sum': '$firstCount' }
53 }}
54 ]
55 }}
56])
57
58for i in result:
59 print(i)
3

确保您的连接字符串包含数据库用户的档案。要了解详情,请参阅通过驱动程序连接

4
python search-with-unionwith-query.py
{'name': 'XLR8 Mobile', 'number_of_employees': 21, 'founded_year': 2006, 'score': 2.0815043449401855, 'source': 'companies'}
{'name': 'Pulse Mobile', 'number_of_employees': None, 'founded_year': None, 'score': 2.0815043449401855, 'source': 'companies'}
{'name': 'T-Mobile', 'number_of_employees': None, 'founded_year': None, 'score': 2.0815043449401855, 'source': 'companies'}
{'business_name': 'T. MOBILE', 'address': {'city': 'BROOKLYN', 'zip': 11209, 'street': '86TH ST', 'number': 440}, 'source': 'inspections', 'score': 2.900916337966919}
{'business_name': 'BOOST MOBILE', 'address': {'city': 'BRONX', 'zip': 10458, 'street': 'E FORDHAM RD', 'number': 261}, 'source': 'inspections', 'score': 2.900916337966919}
{'business_name': 'SPRING MOBILE', 'address': {'city': 'SOUTH RICHMOND HILL', 'zip': 11419, 'street': 'LIBERTY AVE', 'number': 12207}, 'source': 'inspections', 'score': 2.900916337966919}
python search-with-unionwith-query.py
{
'allDocs': [
{'name': 'XLR8 Mobile', 'number_of_employees': 21, 'founded_year': 2006, 'score': 3.33040714263916, 'source': 'companies', 'source_count': 52},
{'name': 'Pulse Mobile', 'number_of_employees': None, 'founded_year': None, 'score': 3.33040714263916, 'source': 'companies', 'source_count': 52},
{'name': 'T-Mobile', 'number_of_employees': None, 'founded_year': None, 'score': 3.33040714263916, 'source': 'companies', 'source_count': 52},
{'business_name': 'T. MOBILE', 'address': {'city': 'BROOKLYN', 'zip': 11209, 'street': '86TH ST', 'number': 440}, 'score': 2.900916337966919, 'source': 'inspections', 'source_count': 456},
{'business_name': 'BOOST MOBILE', 'address': {'city': 'BRONX', 'zip': 10458, 'street': 'E FORDHAM RD', 'number': 261}, 'score': 2.900916337966919, 'source': 'inspections', 'source_count': 456},
{'business_name': 'SPRING MOBILE', 'address': {'city': 'SOUTH RICHMOND HILL', 'zip': 11419, 'street': 'LIBERTY AVE', 'number': 12207}, 'score': 2.900916337966919, 'source': 'inspections', 'source_count': 456}
],
'totalCount': [
{'_id': 'companies', 'totalCount': 52},
{'_id': 'inspections', 'totalCount': 456}
]
}

本教程介绍如何创建索引,并针对示例数据集中的 sample_supplies.sales 集合和新的 sample_supplies.purchaseOrders 运行查询。

按需具体化视图是使用 $merge 聚合管道阶段创建和更新的集合。您可以在物化视图上创建 Atlas Search 索引,然后使用 $search 聚合管道阶段对物化视图运行查询。

本教程将指导您完成以下步骤:

  1. sample_supplies 数据库中创建名为 purchaseOrders 的集合。

  2. 创建两个定时触发器:

    • updateMonthlySales,带有一个名为 updateMonthlySales 的函数,该函数使用示例 sample_supplies.sales 集合中的数据初始化 monthlyPhoneTransactions 物化视图。

    • updateMonthlyPurchaseOrders,其中包含一个名为 updateMonthlyPurchaseOrders 的函数,该函数使用 sample_supplies.purchaseOrders 集合中的数据来更新 monthlyPhoneTransactions 物化视图。

  3. monthlyPhoneTransactions 物化视图上创建 Atlas Search 索引。

  4. monthlyPhoneTransactions 物化视图运行查询。

1
  1. 在终端窗口中打开mongosh并连接到集群。 有关连接的详细说明,请参阅通过mongosh连接。

  2. 使用 sample_supplies 数据库:

    use sample_supplies
2

添加purchaseOrders 集合,其中包含自 2018 年一月份起的新手机采购订单数据。运行以下命令:

db.purchaseOrders.insertMany( [
{
saleDate: ISODate("2018-01-23T21:06:49.506Z"),
items: [
{
name: 'printer paper',
tags: [ 'office', 'stationary' ],
price: Decimal128("40.01"),
quantity: 2
},
{
name: 'notepad',
tags: [ 'office', 'writing', 'school' ],
price: Decimal128("35.29"),
quantity: 2
},
{
name: 'pens',
tags: [ 'writing', 'office', 'school', 'stationary' ],
price: Decimal128("56.12"),
quantity: 5
},
{
name: 'backpack',
tags: [ 'school', 'travel', 'kids' ],
price: Decimal128("77.71"),
quantity: 2
},
{
name: 'notepad',
tags: [ 'office', 'writing', 'school' ],
price: Decimal128("18.47"),
quantity: 2
},
{
name: 'envelopes',
tags: [ 'stationary', 'office', 'general' ],
price: Decimal128("19.95"),
quantity: 8
},
{
name: 'envelopes',
tags: [ 'stationary', 'office', 'general' ],
price: Decimal128("8.08"),
quantity: 3
},
{
name: 'binder',
tags: [ 'school', 'general', 'organization' ],
price: Decimal128("14.16"),
quantity: 3
}
],
storeLocation: 'Denver',
customer: {
gender: 'M',
age: 42,
email: 'cauho@witwuta.sv',
satisfaction: 4
},
couponUsed: true,
purchaseMethod: 'Phone'
}
])
db.purchaseOrders.insertMany( [
{
saleDate: ISODate("2018-01-25T10:01:02.918Z"),
items: [
{
name: 'envelopes',
tags: [ 'stationary', 'office', 'general' ],
price: Decimal128("8.05"),
quantity: 10
},
{
name: 'binder',
tags: [ 'school', 'general', 'organization' ],
price: Decimal128("28.31"),
quantity: 9
},
{
name: 'notepad',
tags: [ 'office', 'writing', 'school' ],
price: Decimal128("20.95"),
quantity: 3
},
{
name: 'laptop',
tags: [ 'electronics', 'school', 'office' ],
price: Decimal128("866.5"),
quantity: 4
},
{
name: 'notepad',
tags: [ 'office', 'writing', 'school' ],
price: Decimal128("33.09"),
quantity: 4
},
{
name: 'printer paper',
tags: [ 'office', 'stationary' ],
price: Decimal128("37.55"),
quantity: 1
},
{
name: 'backpack',
tags: [ 'school', 'travel', 'kids' ],
price: Decimal128("83.28"),
quantity: 2
},
{
name: 'pens',
tags: [ 'writing', 'office', 'school', 'stationary' ],
price: Decimal128("42.9"),
quantity: 4
},
{
name: 'envelopes',
tags: [ 'stationary', 'office', 'general' ],
price: Decimal128("16.68"),
quantity: 2
}
],
storeLocation: 'Seattle',
customer: { gender: 'M', age: 50, email: 'keecade@hem.uy', satisfaction: 5 },
couponUsed: false,
purchaseMethod: 'Phone'
}
])
3

查询 purchaseOrders 集合以确认新的采购订单条目。

db.purchaseOrders.find().sort( {saleDate: -1} )
{
_id: ObjectId("62434c07d574cd0ce200ba75"),
saleDate: ISODate("2018-01-25T10:01:02.918Z"),
items: [
{
name: 'envelopes',
tags: [ 'stationary', 'office', 'general' ],
price: Decimal128("8.05"),
quantity: 10
},
{
name: 'binder',
tags: [ 'school', 'general', 'organization' ],
price: Decimal128("28.31"),
quantity: 9
},
{
name: 'notepad',
tags: [ 'office', 'writing', 'school' ],
price: Decimal128("20.95"),
quantity: 3
},
{
name: 'laptop',
tags: [ 'electronics', 'school', 'office' ],
price: Decimal128("866.5"),
quantity: 4
},
{
name: 'notepad',
tags: [ 'office', 'writing', 'school' ],
price: Decimal128("33.09"),
quantity: 4
},
{
name: 'printer paper',
tags: [ 'office', 'stationary' ],
price: Decimal128("37.55"),
quantity: 1
},
{
name: 'backpack',
tags: [ 'school', 'travel', 'kids' ],
price: Decimal128("83.28"),
quantity: 2
},
{
name: 'pens',
tags: [ 'writing', 'office', 'school', 'stationary' ],
price: Decimal128("42.9"),
quantity: 4
},
{
name: 'envelopes',
tags: [ 'stationary', 'office', 'general' ],
price: Decimal128("16.68"),
quantity: 2
}
],
storeLocation: 'Seattle',
customer: {
gender: 'M',
age: 50,
email: 'keecade@hem.uy',
satisfaction: 5
},
couponUsed: false,
purchaseMethod: 'Phone'
},
{
_id: ObjectId("62434c07d574cd0ce200ba74"),
saleDate: ISODate("2018-01-23T21:06:49.506Z"),
items: [
{
name: 'printer paper',
tags: [ 'office', 'stationary' ],
price: Decimal128("40.01"),
quantity: 2
},
{
name: 'notepad',
tags: [ 'office', 'writing', 'school' ],
price: Decimal128("35.29"),
quantity: 2
},
{
name: 'pens',
tags: [ 'writing', 'office', 'school', 'stationary' ],
price: Decimal128("56.12"),
quantity: 5
},
{
name: 'backpack',
tags: [ 'school', 'travel', 'kids' ],
price: Decimal128("77.71"),
quantity: 2
},
{
name: 'notepad',
tags: [ 'office', 'writing', 'school' ],
price: Decimal128("18.47"),
quantity: 2
},
{
name: 'envelopes',
tags: [ 'stationary', 'office', 'general' ],
price: Decimal128("19.95"),
quantity: 8
},
{
name: 'envelopes',
tags: [ 'stationary', 'office', 'general' ],
price: Decimal128("8.08"),
quantity: 3
},
{
name: 'binder',
tags: [ 'school', 'general', 'organization' ],
price: Decimal128("14.16"),
quantity: 3
}
],
storeLocation: 'Denver',
customer: {
gender: 'M',
age: 42,
email: 'cauho@witwuta.sv',
satisfaction: 4
},
couponUsed: true,
purchaseMethod: 'Phone'
}

这两个查询结果反映采购订单数据在 2018 的 1 月结束。

注意

要创建触发器,您必须拥有 Project Owner 或更高的项目访问权限。

在以下过程中,您将创建触发器以创建物化视图,并安排函数每天更新物化视图。展开以下部分可查看每个触发器的步骤:

monthlyPhoneTransactions 集合上创建 Atlas Search 索引。

1

警告

导航改进正在进行中

我们目前正在逐步推出改进的全新导航体验。如果以下步骤与您在 Atlas UI 中的视图不符,请参阅预览文档

  1. 如果尚未显示,请从导航栏上的 Organizations 菜单中选择包含所需项目的组织。

  2. 如果尚未显示,请从导航栏的Projects菜单中选择所需的项目。

  3. 如果尚未出现,请单击侧边栏中的 Clusters(集群)。

    会显示集群页面。

2

您可以从侧边栏、 Data Explorer 或集群详细信息页面转到 Atlas Search 页面。

  1. 在侧边栏中,单击 Services 标题下的 Atlas Search

    如果没有集群,则请单击 Create cluster 来创建一个。要了解更多信息,请参阅创建集群

  2. 如果您的项目有多个集群,请从 Select cluster 下拉列表中选择要使用的集群,然后单击 Go to Atlas Search

    将显示 Atlas Search 页面。

  1. 单击集群的对应 Browse Collections 按钮。

  2. 展开数据库并选择集合。

  3. 单击该集合的 Search Indexes 标签页。

    将显示 Atlas Search 页面。

  1. 单击集群的名称。

  2. 单击 Atlas Search 标签页。

    将显示 Atlas Search 页面。

3
4

在页面上进行以下选择,然后单击 Next

Search Type

选择 Atlas Search 索引类型。

Index Name and Data Source

指定以下信息:

  • Index Name: monthlyPhoneTransactions

  • Database and Collection:

    • sample_supplies database

    • monthlyPhoneTransactions 集合

Configuration Method

For a guided experience, select Visual Editor.

To edit the raw index definition, select JSON Editor.

注意

您的 Atlas Search 索引默认名为 default。如果保留此名称,则对于任何未在其操作符中指定不同 index选项的 Atlas Search 查询,您的搜索索引将成为默认搜索索引。如果您要创建多个索引,我们建议您在所有索引中保持一致且具有描述性的命名规则。

5
6
7

此时将显示一个模态窗口,让您知道索引正在构建中。点击 Close 按钮。

8

新创建的索引会出现在 Atlas Search 标签页上。在构建索引期间,Status 字段显示为 Building。索引构建完成后,Status 字段将显示为Active

注意

较大的集合需要较长的索引时间。索引构建完成后,您将收到电子邮件通知。

针对新更新并编入索引的 monthlyPhoneTransactions 集合运行查询。

1

在终端窗口中打开mongosh并连接到集群。 有关连接的详细说明,请参阅通过mongosh连接。

2

mongosh 提示符下运行以下命令:

use sample_supplies
3

以下查询统计 monthlyPhoneTransactions 中总销售额大于或等于 10000 美元的月份数:

db.monthlyPhoneTransactions.aggregate([
{
$search: {
"index": "monthlySalesIndex",
"range": {
"gt": 10000,
"path": ["sales_price"]
}
}
},
{
$count: 'months_w_over_10000'
},
])

上述查询返回 4,表示在 monthlyPhoneTransactions 物化视图中的所有月份中,只有 4 个月的总销售额大于或等于 10000 美元。此结果反映了 sample_supplies.salessample_supplies.purchaseOrders 集合的数据。

有关聚合管道的完整文档,请参阅 MongoDB 服务器手册。

后退

嵌入式文档

在此页面上