このページに含まれるチュートリアルでは、複数のコレクションにわたって Atlas Search クエリを実行可能な以下の方法について説明しています。
コレクションを結合してその全体を検索するには、$lookup と $search を併用します。
複数のコレクションからの検索結果を結合するには、 $unionWith と $search を使用します。
開始する前に、Atlas クラスターが前提条件に記載されている要件を満たしていることを確認してください。
➤ このページの [Select your 言語を選択する)] ドロップダウンメニューを使用して、このページの例えの言語を設定します。
結合されたコレクションを検索
v6.0 以降、 MongoDB$lookup
集計ステージは、$search
オプション内での$lookup
pipeline
をサポートします。$lookup
を使用すると、クエリ時に同じデータベース内の複数のコレクションを結合し、$search
クエリを実行して検索をさらに絞り込むことができます。
このチュートリアルでは、 データベース内の コレクションと コレクションに対して、 を使用して クエリを実行する方法を説明します。$lookup
$search
accounts
customers
sample_analytics
次の手順が必要です。
デフォルトの Atlas Search インデックスを
sample_analytics
データベースのaccounts
コレクションに作成します。$lookup
クエリを$search
で実行し、accounts
コレクションにCurrencyService
とInvestmentStock
商品の両方の購入歴があるアカウントを持つカスタマーをcustomers
コレクションから見つけます。
Considerations
$lookup
クエリを $search
で実行するには、クラスターで MongoDB v6.0 以降を実行している必要があります。MongoDB のバージョンをアップグレードするには、「クラスターのメジャー MongoDB バージョンをアップグレードする」を参照してください。
$lookup
クエリはあまり効率的ではありません。Atlas Search ではコレクション内の各ドキュメントを対象に、データベースで完全なドキュメント検索(ルックアップ)が実行されるためです。
詳細については、「$lookup
操作の削減」を参照してください。
Atlas Search インデックスの作成
sample_analytics.accounts
コレクション内のすべてのフィールドにlookup-with-search-tutorial
という名前の Atlas Search インデックスを作成します。
Atlas Atlasで、プロジェクトの {0 ページにGoします。GoClusters
警告
ナビゲーションの改善が進行中
現在、新しく改善されたナビゲーション エクスペリエンスを展開しています。次の手順が Atlas UIのビューと一致しない場合は、プレビュー ドキュメントを参照してください。
まだ表示されていない場合は、希望するプロジェクトを含む組織を選択しますナビゲーション バーのOrganizationsメニュー
まだ表示されていない場合は、ナビゲーション バーのProjectsメニューから目的のプロジェクトを選択します。
まだ表示されていない場合は、サイドバーの [Clusters] をクリックします。
[ Clusters (クラスター) ] ページが表示されます。
インデックスの設定を開始します。
ページで次の選択を行い、Next をクリックしてください。
Search Type | Atlas Search のインデックスタイプを選択します。 |
Index Name and Data Source | 以下の情報を指定してください。
|
Configuration Method | For a guided experience, select Visual Editor. To edit the raw index definition, select JSON Editor. |
注意
Atlas Search インデックスのデフォルト名は「default
」です。この名前を変更しない場合、Atlas Search クエリのデフォルトの検索インデックスが使用され、その演算子では別の index
オプションは指定されません。複数のインデックスを作成する場合は、インデックス全体で一貫性があり、内容がわかる命名規則を維持することをお勧めします。
インデックスの定義を指定します。
次のインデックス定義は、コレクション内のサポートされている型のフィールドを動的にインデックス化します。 インデックスを作成するには、 インターフェースで または を使用できます。Atlas SearchVisual EditorAtlas SearchJSON EditorAtlas user
コレクションのデフォルトのインデックス定義を確認します。
インデックスの定義を確認します。
インデックス定義は、次のようになります。
{ "mappings": { "dynamic": true } } [Next] をクリックします。
$search
とともに $lookup
を実行し、コレクションを検索する
➤ このページの [言語の選択] ドロップダウンメニューを使用して、このセクションの例の言語を設定します。
Atlas クラスターに接続し、 sample_analytics
データベース内のインデックス付きコレクションに対してサンプル クエリを実行します。
mongosh
内のクラスターに接続します。
ターミナル ウィンドウでmongosh
を開き、クラスターに接続します。 接続の詳細な手順については、「 mongosh
経由での接続 」を参照してください。
sample_analytics
データベースに切り替えます。
mongosh
プロンプトで次のコマンドを実行します。
use sample_analytics
switched to db sample_analytics
次の $lookup
を Atlas Search $search
クエリで実行します。
次のクエリでは、次のステージを使用します。
$lookup
必要に応じて、次の操作を実行します。customers
accounts
sample_analytics
カスタマーのアカウント IDaccounts
purchases
に基づいて、 データベース内の コレクションと コレクションを結合し、 コレクションから一致するドキュメントを という名前の配列フィールドに返します。サブパイプラインの
$search
ステージを使用して、must
がCurrencyService
とInvestmentStock
の両方を優先して、5000
から10000
の注文制限で購入したカスタマー アカウントを検索します。
$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' ] } ] } ]
MongoDB Compass のクラスターに接続します。
MongoDB Compass を開き、クラスターに接続します。 接続の詳細な手順については、「 Compass 経由での接続 」を参照してください。
コレクションに対して Atlas Search クエリを実行します。
次のクエリでは、次のステージを使用します。
$lookup
必要に応じて、次の操作を実行します。customers
accounts
sample_analytics
カスタマーのアカウント IDaccounts
purchases
に基づいて、 データベース内の コレクションと コレクションを結合し、 コレクションから一致するドキュメントを という名前の配列フィールドに返します。サブパイプラインの
$search
ステージを使用して、must
がCurrencyService
とInvestmentStock
の両方を優先して、5000
から10000
の注文制限で購入したカスタマー アカウントを検索します。
$limit
ステージを使用して、出力を5
の結果に制限します。$project
ステージを使用して、結果から指定されたフィールドを除外します。
MongoDB Compass でこのクエリを実行するには:
[Aggregations] タブをクリックします。
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)
クエリをコピーして Program.cs
ファイルに貼り付けます。
次のクエリでは、次のステージを使用します。
$lookup
必要に応じて、次の操作を実行します。customers
accounts
sample_analytics
カスタマーのアカウント IDaccounts
purchases
に基づいて、 データベース内の コレクションと コレクションを結合し、 コレクションから一致するドキュメントを という名前の配列フィールドに返します。サブパイプラインの
$search
ステージを使用して、must
がCurrencyService
とInvestmentStock
の両方を優先して、5000
から10000
の注文制限で購入したカスタマー アカウントを検索します。
$limit
ステージを使用して、出力を5
の結果に制限します。$project
ステージを使用して、結果から指定されたフィールドを除外します。
1 using MongoDB.Bson; 2 using MongoDB.Bson.Serialization.Attributes; 3 using MongoDB.Bson.Serialization.Conventions; 4 using MongoDB.Driver; 5 using MongoDB.Driver.Core; 6 using MongoDB.Driver.Search; 7 8 public 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 [ ]61 public class AccountDocument { 62 [ ]63 [ ]64 [ ]65 public string Id { get; set; } 66 67 [ ]68 public int AccountId { get; set; } 69 70 [ ]71 public int Limit { get; set; } 72 } 73 74 // define fields in the customers collection 75 [ ]76 public class CustomerDocument { 77 [ ]78 [ ]79 [ ]80 public ObjectId Id { get; set; } 81 82 [ ]83 public string Name { get; set; } 84 85 [ ]86 public string Email { get; set; } 87 88 [ ]89 public bool Active { get; set; } 90 91 [ ]92 public List<int> Accounts { get; set; } 93 } 94 95 // define new array field for matching documents 96 public class CustomerLookedUp: CustomerDocument{ 97 public List<CustomerDocument> Purchases { get; set; } 98 }
クエリ内の <connection-string>
を置き換え、ファイルを保存します。
接続stringにデータベースユーザーの認証情報が含まれていることを確認します。 詳しくは、「ドライバーによる接続 」を参照してください。
Program.cs
ファイルをコンパイルして実行します。
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"] } ] }
クエリをコピーして lookup-with-search-query.go
ファイルに貼り付けます。
次のクエリでは、次のステージを使用します。
$lookup
必要に応じて、次の操作を実行します。customers
accounts
sample_analytics
カスタマーのアカウント IDaccounts
purchases
に基づいて、 データベース内の コレクションと コレクションを結合し、 コレクションから一致するドキュメントを という名前の配列フィールドに返します。サブパイプラインの
$search
ステージを使用して、must
がCurrencyService
とInvestmentStock
の両方を優先して、5000
から10000
の注文制限で購入したカスタマー アカウントを検索します。
$limit
ステージを使用して、出力を5
の結果に制限します。$project
ステージを使用して、結果から指定されたフィールドを除外します。
1 package main 2 3 import ( 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 13 func 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 }
クエリ内の <connection-string>
を置き換え、ファイルを保存します。
接続stringにデータベースユーザーの認証情報が含まれていることを確認します。 詳しくは、「ドライバーによる接続 」を参照してください。
コマンドを実行して、コレクションをクエリします。
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":[]}
クエリをコピーして LookupWithSearchQuery.java
ファイルに貼り付けます。
次のクエリでは、次のステージを使用します。
$lookup
必要に応じて、次の操作を実行します。customers
accounts
sample_analytics
カスタマーのアカウント IDaccounts
purchases
に基づいて、 データベース内の コレクションと コレクションを結合し、 コレクションから一致するドキュメントを という名前の配列フィールドに返します。サブパイプラインの
$search
ステージを使用して、must
がCurrencyService
とInvestmentStock
の両方を優先して、5000
から10000
の注文制限で購入したカスタマー アカウントを検索します。
$limit
ステージを使用して、出力を5
の結果に制限します。$project
ステージを使用して、結果から指定されたフィールドを除外します。
1 import static com.mongodb.client.model.Aggregates.limit; 2 import static com.mongodb.client.model.Aggregates.project; 3 import static com.mongodb.client.model.Projections.*; 4 import java.util.Arrays; 5 import com.mongodb.client.MongoClient; 6 import com.mongodb.client.MongoClients; 7 import com.mongodb.client.MongoCollection; 8 import com.mongodb.client.MongoDatabase; 9 import org.bson.Document; 10 11 public 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 環境でサンプル コードを実行するには、 ファイルのインポート ステートメントの上に次のコードを追加します。
package com.mongodb.drivers;
クエリ内の <connection-string>
を置き換え、ファイルを保存します。
接続stringにデータベースユーザーの認証情報が含まれていることを確認します。 詳しくは、「ドライバーによる接続 」を参照してください。
LookupWithSearchQuery.java
ファイルをコンパイルして実行します。
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"]}]}
クエリをコピーして LookupWithSearchQuery.kt
ファイルに貼り付けます。
次のクエリでは、次のステージを使用します。
$lookup
必要に応じて、次の操作を実行します。customers
accounts
sample_analytics
カスタマーのアカウント IDaccounts
purchases
に基づいて、 データベース内の コレクションと コレクションを結合し、 コレクションから一致するドキュメントを という名前の配列フィールドに返します。サブパイプラインの
$search
ステージを使用して、must
がCurrencyService
とInvestmentStock
の両方を優先して、5000
から10000
の注文制限で購入したカスタマー アカウントを検索します。
$limit
ステージを使用して、出力を5
の結果に制限します。$project
ステージを使用して、結果から指定されたフィールドを除外します。
1 import com.mongodb.client.model.Aggregates.limit 2 import com.mongodb.client.model.Aggregates.project 3 import com.mongodb.client.model.Projections.* 4 import com.mongodb.kotlin.client.coroutine.MongoClient 5 import kotlinx.coroutines.runBlocking 6 import org.bson.Document 7 import java.util.* 8 9 fun 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 }
クエリ内の <connection-string>
を置き換え、ファイルを保存します。
接続stringにデータベースユーザーの認証情報が含まれていることを確認します。 詳しくは、「ドライバーによる接続 」を参照してください。
LookupWithSearchQuery.kt
ファイルを実行します。
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]}}]}}
サンプルクエリをコピーして lookup-with-search-query.js
ファイルに貼り付けます。
次のクエリでは、次のステージを使用します。
$lookup
必要に応じて、次の操作を実行します。customers
accounts
sample_analytics
カスタマーのアカウント IDaccounts
purchases
に基づいて、 データベース内の コレクションと コレクションを結合し、 コレクションから一致するドキュメントを という名前の配列フィールドに返します。サブパイプラインの
$search
ステージを使用して、must
がCurrencyService
とInvestmentStock
の両方を優先して、5000
から10000
の注文制限で購入したカスタマー アカウントを検索します。
$limit
ステージを使用して、出力を5
の結果に制限します。$project
ステージを使用して、結果から指定されたフィールドを除外します。
1 const MongoClient = require("mongodb").MongoClient; 2 const assert = require("assert"); 3 4 const 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 55 MongoClient.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 );
クエリ内の <connection-string>
を置き換え、ファイルを保存します。
接続stringにデータベースユーザーの認証情報が含まれていることを確認します。 詳しくは、「ドライバーによる接続 」を参照してください。
コレクションをクエリします。
次のコマンドを実行して、コレクションをクエリします。
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] } ] }
クエリをコピーして lookup-with-search-query.py
ファイルに貼り付けます。
次のクエリでは、次のステージを使用します。
$lookup
必要に応じて、次の操作を実行します。customers
accounts
sample_analytics
カスタマーのアカウント IDaccounts
purchases
に基づいて、 データベース内の コレクションと コレクションを結合し、 コレクションから一致するドキュメントを という名前の配列フィールドに返します。サブパイプラインの
$search
ステージを使用して、must
がCurrencyService
とInvestmentStock
の両方を優先して、5000
から10000
の注文制限で購入したカスタマー アカウントを検索します。
$limit
ステージを使用して、出力を5
の結果に制限します。$project
ステージを使用して、結果から指定されたフィールドを除外します。
1 import pymongo 2 3 # connect to your Atlas cluster 4 client = pymongo.MongoClient('<connection-string>') 5 6 # define pipeline 7 pipeline = [ 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 56 result = client['sample_analytics']['customers'].aggregate(pipeline) 57 58 # print results 59 for i in result: 60 print(i)
クエリ内の <connection-string>
を置き換え、ファイルを保存します。
接続stringにデータベースユーザーの認証情報が含まれていることを確認します。 詳しくは、「ドライバーによる接続 」を参照してください。
コマンドを実行して、コレクションをクエリします。
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
$unionWith
pipeline
オプション内での をサポートします。$unionWith
を使用すると、結果セット内の同じデータベース内の複数のコレクションからの$search
の結果を組み合わせることができます。
警告
クエリで $unionWith
を $search
とともにサブパイプライン内で使用している場合、コレクションが複数のシャードに分散されていないと、MongoDB v7.0 を実行するレプリカセットからシャーディングされたクラスターへのアップグレード中に失敗する可能性があります。これを回避するには、クラスターに 2 つ以上のシャードをデプロイし、複数のチャンクが複数のシャードに分散されるようにコレクションをシャーディングしてください。
このチュートリアルでは、 データベース内の コレクションと コレクションに対して、 を使用して クエリを実行する方法を説明します。$unionWith
$search
companies
inspections
sample_training
次の手順が必要です。
sample_training
データベースのcompanies
とinspections
コレクションでデフォルトの Atlas Search インデックスを作成します。$unionWith
クエリを$search
で実行して、companies
とinspections
コレクションの両方に含まれる会社のうちそれぞれの名前にmobile
がある会社を結合します。
注意
$unionWith
$search
を使用して クエリを実行するには、クラスターでMongoDB v6.0 以上を実行する必要があります。 MongoDBのバージョンをアップグレードするには、「 クラスターのメジャーMongoDBバージョンのアップグレード 」を参照してください。
Atlas Search インデックスの作成
このセクションでは、 sample_training
データベースのcompanies
コレクション内のすべてのフィールドにdefault
という名前の Atlas Search インデックスを作成します。 sample_training
データベース内のinspections
コレクションのすべてのフィールドに、 default
という名前の別の Atlas Search インデックスを作成します。 コレクションごとに次の手順を実行する必要があります。
AtlasGoClustersAtlas で、プロジェクトの ページにGoします。
警告
ナビゲーションの改善が進行中
現在、新しく改良されたナビゲーション エクスペリエンスを導入中です。次の手順が Atlas UI の表示と一致しない場合は、プレビュー ドキュメントを参照してください。
まだ表示されていない場合は、希望するプロジェクトを含む組織を選択しますナビゲーション バーのOrganizationsメニュー
まだ表示されていない場合は、ナビゲーション バーのProjectsメニューから目的のプロジェクトを選択します。
まだ表示されていない場合は、サイドバーの [Clusters] をクリックします。
[ Clusters (クラスター) ] ページが表示されます。
インデックスの設定を開始します。
ページで次の選択を行い、Next をクリックしてください。
Search Type | Atlas Search のインデックスタイプを選択します。 |
Index Name and Data Source | 以下の情報を指定してください。
|
Configuration Method | For a guided experience, select Visual Editor. To edit the raw index definition, select JSON Editor. |
注意
Atlas Search インデックスのデフォルト名は「default
」です。この名前を変更しない場合、Atlas Search クエリのデフォルトの検索インデックスが使用され、その演算子では別の index
オプションは指定されません。複数のインデックスを作成する場合は、インデックス全体で一貫性があり、内容がわかる命名規則を維持することをお勧めします。
インデックスの定義を指定します。
次のインデックス定義は、コレクション内のサポートされている型のフィールドを動的にインデックス化します。 インデックスを作成するには、 インターフェースで または を使用できます。Atlas SearchVisual EditorAtlas SearchJSON EditorAtlas user
コレクションの"default"
インデックス定義を確認します。
インデックスの定義を確認します。
インデックス定義は、次の例のようになります。
{ "mappings": { "dynamic": true } }
$search
とともに $unionWith
を実行し、コレクションを検索する
このセクションでは、Atlas クラスターに接続し、 sample_training
データベース内のインデックス作成されたコレクションに対してサンプル クエリを実行します。
mongosh
内のクラスターに接続します。
ターミナル ウィンドウでmongosh
を開き、クラスターに接続します。 接続の詳細な手順については、「 mongosh
経由での接続 」を参照してください。
sample_training
データベースに切り替えます。
mongosh
プロンプトで次のコマンドを実行します。
use sample_training
switched to db sample_training
次の $unionWith
を Atlas Search $search
クエリとともに実行します。
次のクエリは、companies
inspections
mobile
name
コレクションとbusiness_name
コレクションの両方で、それぞれ フィールドと フィールドで というタームを検索します。
このクエリでは、次のステージを使用します。
$search
は、名前にmobile
が含まれる会社を検索します。$unionWith
必要に応じて、次の操作を実行します。サブパイプラインの
$search
ステージを使用して、名前にmobile
が含まれる会社の検査を検索します。コレクションと
companies
inspections
コレクションのドキュメントの和集合を実行します。
$set
ステージで、出力ドキュメントのコレクションを識別するsource
という名前の新しいフィールドを追加します。
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
stageを次のように設定します。指定されたフィールドのみを結果に含めます。
score
という名前のフィールドを追加します。
$addFields
ステージでは、次の新しいフィールドを追加します。出力ドキュメントのコレクションを識別する
source
という名前の新しいフィールド。出力ドキュメント数を示すフィールド名
source_count
。
$unionWith
必要に応じて、次の操作を実行します。サブパイプラインの
$search
ステージを使用して、名前にmobile
が含まれる会社の検査を検索します。コレクションと
companies
inspections
コレクションのドキュメントの和集合を実行します。
$project
stageを次のように設定します。指定されたフィールドのみを結果に含めます。
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") } ] } ]
MongoDB Compass のクラスターに接続します。
MongoDB Compass を開き、クラスターに接続します。 接続の詳細な手順については、「 Compass 経由での接続 」を参照してください。
コレクションに対して Atlas Search クエリを実行します。
次のクエリは、companies
inspections
mobile
name
コレクションとbusiness_name
コレクションの両方で、それぞれ フィールドと フィールドで というタームを検索します。
MongoDB Compass でこのクエリを実行するには:
[Aggregations] タブをクリックします。
Select...をクリックし、ドロップダウンからステージを選択し、そのステージのクエリを追加して、次の各パイプライン ステージを構成します。 ステージを追加するには、 Add Stageをクリックします。
このクエリでは、次のステージを使用します。
$search
は、名前にmobile
が含まれる会社を検索します。$unionWith
必要に応じて、次の操作を実行します。サブパイプラインの
$search
ステージを使用して、名前にmobile
が含まれる会社の検査を検索します。コレクションと
companies
inspections
コレクションのドキュメントの和集合を実行します。
$set
ステージで、出力ドキュメントのコレクションを識別するsource
という名前の新しいフィールドを追加します。
パイプラインステージクエリ$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
stageを次のように設定します。指定されたフィールドのみを結果に含めます。
score
という名前のフィールドを追加します。
$addFields
ステージでは、次の新しいフィールドを追加します。出力ドキュメントのコレクションを識別する
source
という名前の新しいフィールド。出力ドキュメント数を示すフィールド名
source_count
。
$unionWith
必要に応じて、次の操作を実行します。サブパイプラインの
$search
ステージを使用して、名前にmobile
が含まれる会社の検査を検索します。コレクションと
companies
inspections
コレクションのドキュメントの和集合を実行します。
$project
stageを次のように設定します。指定されたフィールドのみを結果に含めます。
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
クエリをコピーして Program.cs
ファイルに貼り付けます。
次のクエリは、companies
inspections
mobile
name
コレクションとbusiness_name
コレクションの両方で、それぞれ フィールドと フィールドで というタームを検索します。
このクエリでは、次のステージを使用します。
$search
は、名前にmobile
が含まれる会社を検索します。$unionWith
必要に応じて、次の操作を実行します。サブパイプラインの
$search
ステージを使用して、名前にmobile
が含まれる会社の検査を検索します。コレクションと
companies
inspections
コレクションのドキュメントの和集合を実行します。
$set
ステージで、出力ドキュメントのコレクションを識別するsource
という名前の新しいフィールドを追加します。
1 using MongoDB.Bson; 2 using MongoDB.Driver; 3 using MongoDB.Driver.Search; 4 5 public 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
stageを次のように設定します。指定されたフィールドのみを結果に含めます。
score
という名前のフィールドを追加します。
$addFields
ステージでは、次の新しいフィールドを追加します。出力ドキュメントのコレクションを識別する
source
という名前の新しいフィールド。出力ドキュメント数を示すフィールド名
source_count
。
$unionWith
必要に応じて、次の操作を実行します。サブパイプラインの
$search
ステージを使用して、名前にmobile
が含まれる会社の検査を検索します。コレクションと
companies
inspections
コレクションのドキュメントの和集合を実行します。
$project
stageを次のように設定します。指定されたフィールドのみを結果に含めます。
score
という名前のフィールドを追加します。
$limit
ステージを使用して、各コレクションからの出力を3
の結果に制限します。$set
ステージでは、次の新しいフィールドを追加します。出力ドキュメントのコレクションを識別する
source
という名前の新しいフィールド。出力ドキュメント数を表示する
source_count
という名前の新しいフィールド。
1 using MongoDB.Bson; 2 using MongoDB.Driver; 3 4 public 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 }
クエリ内の <connection-string>
を置き換え、ファイルを保存します。
接続stringにデータベースユーザーの認証情報が含まれていることを確認します。 詳しくは、「ドライバーによる接続 」を参照してください。
Program.cs
ファイルをコンパイルして実行します。
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) } ] }
クエリをコピーして search-with-unionwith-query.go
ファイルに貼り付けます。
次のクエリは、companies
inspections
mobile
name
コレクションとbusiness_name
コレクションの両方で、それぞれ フィールドと フィールドで というタームを検索します。
このクエリでは、次のステージを使用します。
$search
は、名前にmobile
が含まれる会社を検索します。$unionWith
必要に応じて、次の操作を実行します。サブパイプラインの
$search
ステージを使用して、名前にmobile
が含まれる会社の検査を検索します。コレクションと
companies
inspections
コレクションのドキュメントの和集合を実行します。
$set
ステージで、出力ドキュメントのコレクションを識別するsource
という名前の新しいフィールドを追加します。
1 package main 2 3 import ( 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 13 func 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
stageを次のように設定します。指定されたフィールドのみを結果に含めます。
score
という名前のフィールドを追加します。
$addFields
ステージでは、次の新しいフィールドを追加します。出力ドキュメントのコレクションを識別する
source
という名前の新しいフィールド。出力ドキュメント数を示すフィールド名
source_count
。
$unionWith
必要に応じて、次の操作を実行します。サブパイプラインの
$search
ステージを使用して、名前にmobile
が含まれる会社の検査を検索します。コレクションと
companies
inspections
コレクションのドキュメントの和集合を実行します。
$project
stageを次のように設定します。指定されたフィールドのみを結果に含めます。
score
という名前のフィールドを追加します。
$limit
ステージを使用して、各コレクションからの出力を3
の結果に制限します。$set
ステージでは、次の新しいフィールドを追加します。出力ドキュメントのコレクションを識別する
source
という名前の新しいフィールド。出力ドキュメント数を表示する
source_count
という名前の新しいフィールド。
1 package main 2 3 import ( 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 13 func 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 }
クエリ内の <connection-string>
を置き換え、ファイルを保存します。
接続stringにデータベースユーザーの認証情報が含まれていることを確認します。 詳しくは、「ドライバーによる接続 」を参照してください。
コマンドを実行して、コレクションをクエリします。
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}] ]} ]
クエリをコピーして SearchWithUnionwithQuery.java
ファイルに貼り付けます。
次のクエリは、companies
inspections
mobile
name
コレクションとbusiness_name
コレクションの両方で、それぞれ フィールドと フィールドで というタームを検索します。
このクエリでは、次のステージを使用します。
$search
は、名前にmobile
が含まれる会社を検索します。$unionWith
必要に応じて、次の操作を実行します。サブパイプラインの
$search
ステージを使用して、名前にmobile
が含まれる会社の検査を検索します。コレクションと
companies
inspections
コレクションのドキュメントの和集合を実行します。
$set
ステージで、出力ドキュメントのコレクションを識別するsource
という名前の新しいフィールドを追加します。
1 import com.mongodb.client.MongoClients; 2 import com.mongodb.client.MongoClient; 3 import com.mongodb.client.MongoDatabase; 4 import org.bson.Document; 5 import java.util.ArrayList; 6 import java.util.Arrays; 7 import java.util.List; 8 9 public 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
stageを次のように設定します。指定されたフィールドのみを結果に含めます。
score
という名前のフィールドを追加します。
$addFields
ステージでは、次の新しいフィールドを追加します。出力ドキュメントのコレクションを識別する
source
という名前の新しいフィールド。出力ドキュメント数を示すフィールド名
source_count
。
$unionWith
必要に応じて、次の操作を実行します。サブパイプラインの
$search
ステージを使用して、名前にmobile
が含まれる会社の検査を検索します。コレクションと
companies
inspections
コレクションのドキュメントの和集合を実行します。
$project
stageを次のように設定します。指定されたフィールドのみを結果に含めます。
score
という名前のフィールドを追加します。
$limit
ステージを使用して、各コレクションからの出力を3
の結果に制限します。$set
ステージでは、次の新しいフィールドを追加します。出力ドキュメントのコレクションを識別する
source
という名前の新しいフィールド。出力ドキュメント数を表示する
source_count
という名前の新しいフィールド。
1 import com.mongodb.client.MongoClients; 2 import com.mongodb.client.MongoCollection; 3 import com.mongodb.client.MongoClient; 4 import org.bson.Document; 5 6 public 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 環境でサンプル コードを実行するには、 ファイルのインポート ステートメントの上に次のコードを追加します。
package com.mongodb.drivers;
クエリ内の <connection-string>
を置き換え、ファイルを保存します。
接続stringにデータベースユーザーの認証情報が含まれていることを確認します。 詳しくは、「ドライバーによる接続 」を参照してください。
UinionwithWithSearchQuery.java
ファイルをコンパイルして実行します。
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} ] }
クエリをコピーして SearchWithUnionwithQuery.kt
ファイルに貼り付けます。
次のクエリは、companies
inspections
mobile
name
コレクションとbusiness_name
コレクションの両方で、それぞれ フィールドと フィールドで というタームを検索します。
このクエリでは、次のステージを使用します。
$search
は、名前にmobile
が含まれる会社を検索します。$unionWith
必要に応じて、次の操作を実行します。サブパイプラインの
$search
ステージを使用して、名前にmobile
が含まれる会社の検査を検索します。コレクションと
companies
inspections
コレクションのドキュメントの和集合を実行します。
$set
ステージで、出力ドキュメントのコレクションを識別するsource
という名前の新しいフィールドを追加します。
1 import com.mongodb.kotlin.client.coroutine.MongoClient 2 import kotlinx.coroutines.runBlocking 3 import org.bson.Document 4 5 fun 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
stageを次のように設定します。指定されたフィールドのみを結果に含めます。
score
という名前のフィールドを追加します。
$addFields
ステージでは、次の新しいフィールドを追加します。出力ドキュメントのコレクションを識別する
source
という名前の新しいフィールド。出力ドキュメント数を示すフィールド名
source_count
。
$unionWith
必要に応じて、次の操作を実行します。サブパイプラインの
$search
ステージを使用して、名前にmobile
が含まれる会社の検査を検索します。コレクションと
companies
inspections
コレクションのドキュメントの和集合を実行します。
$project
stageを次のように設定します。指定されたフィールドのみを結果に含めます。
score
という名前のフィールドを追加します。
$limit
ステージを使用して、各コレクションからの出力を3
の結果に制限します。$set
ステージでは、次の新しいフィールドを追加します。出力ドキュメントのコレクションを識別する
source
という名前の新しいフィールド。出力ドキュメント数を表示する
source_count
という名前の新しいフィールド。
1 import com.mongodb.kotlin.client.coroutine.MongoClient 2 import kotlinx.coroutines.runBlocking 3 import org.bson.Document 4 import java.util.* 5 6 fun 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 }
クエリ内の <connection-string>
を置き換え、ファイルを保存します。
接続stringにデータベースユーザーの認証情報が含まれていることを確認します。 詳しくは、「ドライバーによる接続 」を参照してください。
SearchWithUnionwithQuery.kt
ファイルを実行します。
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}}]}}
サンプルクエリをコピーして search-with-unionwith-query.js
ファイルに貼り付けます。
次のクエリは、companies
inspections
mobile
name
コレクションとbusiness_name
コレクションの両方で、それぞれ フィールドと フィールドで というタームを検索します。
このクエリでは、次のステージを使用します。
$search
は、名前にmobile
が含まれる会社を検索します。$unionWith
必要に応じて、次の操作を実行します。サブパイプラインの
$search
ステージを使用して、名前にmobile
が含まれる会社の検査を検索します。コレクションと
companies
inspections
コレクションのドキュメントの和集合を実行します。
$set
ステージで、出力ドキュメントのコレクションを識別するsource
という名前の新しいフィールドを追加します。
1 const MongoClient = require("mongodb").MongoClient; 2 const assert = require("assert"); 3 4 const 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 43 MongoClient.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
stageを次のように設定します。指定されたフィールドのみを結果に含めます。
score
という名前のフィールドを追加します。
$addFields
ステージでは、次の新しいフィールドを追加します。出力ドキュメントのコレクションを識別する
source
という名前の新しいフィールド。出力ドキュメント数を示すフィールド名
source_count
。
$unionWith
必要に応じて、次の操作を実行します。サブパイプラインの
$search
ステージを使用して、名前にmobile
が含まれる会社の検査を検索します。コレクションと
companies
inspections
コレクションのドキュメントの和集合を実行します。
$project
stageを次のように設定します。指定されたフィールドのみを結果に含めます。
score
という名前のフィールドを追加します。
$limit
ステージを使用して、各コレクションからの出力を3
の結果に制限します。$set
ステージでは、次の新しいフィールドを追加します。出力ドキュメントのコレクションを識別する
source
という名前の新しいフィールド。出力ドキュメント数を表示する
source_count
という名前の新しいフィールド。
1 const MongoClient = require("mongodb").MongoClient; 2 const assert = require("assert"); 3 4 const 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 58 MongoClient.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 );
クエリ内の <connection-string>
を置き換え、ファイルを保存します。
接続stringにデータベースユーザーの認証情報が含まれていることを確認します。 詳しくは、「ドライバーによる接続 」を参照してください。
コレクションをクエリします。
次のコマンドを実行して、コレクションをクエリします。
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 } ] }
クエリをコピーして search-with-unionwith-query.py
ファイルに貼り付けます。
次のクエリは、companies
inspections
mobile
name
コレクションとbusiness_name
コレクションの両方で、それぞれ フィールドと フィールドで というタームを検索します。
このクエリでは、次のステージを使用します。
$search
は、名前にmobile
が含まれる会社を検索します。$unionWith
必要に応じて、次の操作を実行します。サブパイプラインの
$search
ステージを使用して、名前にmobile
が含まれる会社の検査を検索します。コレクションと
companies
inspections
コレクションのドキュメントの和集合を実行します。
$set
ステージで、出力ドキュメントのコレクションを識別するsource
という名前の新しいフィールドを追加します。
1 import pymongo 2 import dns 3 4 client = pymongo.MongoClient('<connection-string>') 5 result = 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 42 for i in result: 43 print(i)
このクエリでは、次のステージを使用します。
$search
は、名前にmobile
が含まれる会社を検索します。$project
stageを次のように設定します。指定されたフィールドのみを結果に含めます。
score
という名前のフィールドを追加します。
$addFields
ステージでは、次の新しいフィールドを追加します。出力ドキュメントのコレクションを識別する
source
という名前の新しいフィールド。出力ドキュメント数を示すフィールド名
source_count
。
$unionWith
必要に応じて、次の操作を実行します。サブパイプラインの
$search
ステージを使用して、名前にmobile
が含まれる会社の検査を検索します。コレクションと
companies
inspections
コレクションのドキュメントの和集合を実行します。
$project
stageを次のように設定します。指定されたフィールドのみを結果に含めます。
score
という名前のフィールドを追加します。
$limit
ステージを使用して、各コレクションからの出力を3
の結果に制限します。$set
ステージでは、次の新しいフィールドを追加します。出力ドキュメントのコレクションを識別する
source
という名前の新しいフィールド。出力ドキュメント数を表示する
source_count
という名前の新しいフィールド。
1 import pymongo 2 import dns 3 4 client = pymongo.MongoClient('<connection-string>') 5 result = 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 58 for i in result: 59 print(i)
クエリ内の <connection-string>
を置き換え、ファイルを保存します。
接続stringにデータベースユーザーの認証情報が含まれていることを確認します。 詳しくは、「ドライバーによる接続 」を参照してください。
コマンドを実行して、コレクションをクエリします。
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} ] }
マテリアライズドビューを使用した Atlas Search クエリの実行
このチュートリアルでは、インデックスを作成し、サンプルデータセットの sample_supplies.sales
コレクションと新しい sample_supplies.purchaseOrders
に対してクエリを実行する方法について説明します。
オンデマンドのマテリアライズドビューは、 $merge
集計パイプライン ステージを使用して作成および更新するコレクションです。 マテリアライズドビューで Atlas Search インデックスを作成し、 $search
集計パイプラインステージを使用してマテリアライズドビューでクエリを実行できます。
このチュートリアルでは、次の手順について説明します。
sample_supplies
データベースにpurchaseOrders
という名前のコレクションを作成します。予定されたトリガーを 2 つ作成する。
updateMonthlySales
は、サンプルsample_supplies.sales
コレクションのデータを使用してmonthlyPhoneTransactions
のマテリアライズドビューを初期化するupdateMonthlySales
という関数です。updateMonthlyPurchaseOrders
は、sample_supplies.purchaseOrders
コレクションのデータを使用してmonthlyPhoneTransactions
のマテリアライズドビューを更新するupdateMonthlyPurchaseOrders
という関数です。
monthlyPhoneTransactions
のマテリアライズドビューに Atlas Search インデックスを作成します。monthlyPhoneTransactions
のマテリアライズドビューでクエリを実行します。
purchaseOrders
コレクションの作成
sample_supplies
データベースに接続します。
ターミナル ウィンドウで
mongosh
を開き、クラスターに接続します。 接続の詳細な手順については、「mongosh
経由での接続 」を参照してください。sample_supplies
データベースを使用します。use sample_supplies
新しい コレクションを追加します。
2018年 1 月からの新しいデバイスの購入注文データを含むpurchaseOrders
コレクションを追加します。 次のコマンドを実行します。
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' } ])
新しいコレクションをクエリします。
新しい購入注文エントリを確認するには、 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' }
2 つのクエリ結果は、発注データが2018の 1 月に終了することを反映しています。
予定されたトリガーを作成する
注意
トリガーを作成するには、プロジェクトに対して Project Owner
以上のアクセス権が必要です。
次の手順では、マテリアライズドビューを作成するトリガーを作成し、マテリアライズドビューを毎日更新する関数をスケジュールします。次のセクションを展開すると、各トリガーの手順が表示されます。
AtlasGoTriggersAtlas で、プロジェクトの ページにGoします。
警告
ナビゲーションの改善が進行中
現在、新しく改良されたナビゲーション エクスペリエンスを導入中です。次の手順が Atlas UI の表示と一致しない場合は、プレビュー ドキュメントを参照してください。
まだ表示されていない場合は、プロジェクトを含む組織をナビゲーション バーの Organizations メニューで選択します。
まだ表示されていない場合は、ナビゲーション バーの Projects メニューからプロジェクトを選択します。
サイドバーで、 Services見出しの下のTriggersをクリックします。
Triggersページが表示されます。
関数を作成する
この trigger の関数は、累積月間売上情報を含む monthlyPhoneTransactions
マテリアライズドビューを定義します。電話で行われた販売の月次売上情報を更新する関数です。
次のコードを関数に貼り付けます。
exports = function(){ var pipeline = [ { $match: {purchaseMethod: "Phone"} }, { $unwind: {path: "$items"}}, { $group: { _id: { $dateToString: { format: "%Y-%m", date: "$saleDate" } }, sales_quantity: { $sum: "$items.quantity"}, sales_price: { $sum: "$items.price"} }}, { $set: { sales_price: { $toDouble: "$sales_price"}}}, { $merge: { into: "monthlyPhoneTransactions", whenMatched: "replace" } } ] var monthlyPhoneTransactions = context.services.get("mongodb-atlas").db("sample_supplies").collection("sales"); return monthlyPhoneTransactions.aggregate(pipeline); };
この関数は、次の集計パイプライン ステージを使用してmonthlyPhoneTransactions
を更新します。
$match
ステージではデータがフィルタリングされ、Phone
中に完了した販売のみが処理されます。$group
ステージでは、売上情報が年月別にグループ化されます。このステージでは、次の形式のドキュメントを出力します。{ "_id" : "<YYYY-mm>", "sales_quantity" : <num>, "sales_amount" : <NumberDecimal> } $set
ステージでは、sales_price
フィールドのデータ型がdouble
に変更されます。 Atlas Search$search
演算子はDecimal128
データ型をサポートしていません。sales_price
フィールドのデータ型を変更すると、Atlas Search インデックスを使用してこのフィールドをクエリできるようになります。$merge
ステージは出力をmonthlyPhoneTransactions
コレクションに書き込みます。このステージでは、
_id
フィールドに基づいて、集計結果内のドキュメントがコレクション内の既存のドキュメントと一致するかどうかが確認されます。
AtlasGoTriggersAtlas で、プロジェクトの ページにGoします。
警告
ナビゲーションの改善が進行中
現在、新しく改良されたナビゲーション エクスペリエンスを導入中です。次の手順が Atlas UI の表示と一致しない場合は、プレビュー ドキュメントを参照してください。
まだ表示されていない場合は、プロジェクトを含む組織をナビゲーション バーの Organizations メニューで選択します。
まだ表示されていない場合は、ナビゲーション バーの Projects メニューからプロジェクトを選択します。
サイドバーで、 Services見出しの下のTriggersをクリックします。
Triggersページが表示されます。
関数を作成する
updateMonthlyPurchaseOrders
関数の仕組み
updateMonthlyPurchaseOrders
関数は、monthlyPhoneTransactions
のマテリアライズド・ビューに月次の累積購買発注情報を追加します。この関数は、電話で行われた購買発注の月次購買発注情報を更新します。次の例では、関数を定義しています。
exports = function(){ var pipeline = [ { $match: {purchaseMethod: "Phone"} }, { $unwind: {path: "$items"}}, { $group: { _id: { $dateToString: { format: "%Y-%m", date: "$saleDate" } }, sales_quantity: { $sum: "$items.quantity"}, sales_price: { $sum: "$items.price"} }}, { $set: { sales_price: { $toDouble: "$sales_price"}}}, { $merge: { into: "monthlyPhoneTransactions", whenMatched: "replace" } } ] var monthlyPhoneTransactions = context.services.get("mongodb-atlas").db("sample_supplies").collection("purchaseOrders"); return monthlyPhoneTransactions.aggregate(pipeline); };
updateMonthlyPurchaseOrders
関数は、updateMonthlySales
関数と同じ集計パイプラインステージを使用して monthlyPhoneTransactions
を更新します。
mongosh
を使用して monthlyPhoneTransactions
コレクションをクエリし、更新を確認する。
db.monthlyPhoneTransactions.find().sort( { _id: -1} )
{ _id: '2018-01', sales_quantity: 66, sales_price: Decimal128("1407.10") }
monthlyPhoneTransactions
のマテリアライズドビューには新しく追加されたデータが表示されます。 上位の結果は、最新のトランザクションが 1 月2018に実行されたことを反映しています。
マテリアライズドビューでの Atlas Search インデックスの作成
monthlyPhoneTransactions
コレクションに Atlas Search インデックスを作成します。
AtlasGoClustersAtlas で、プロジェクトの ページにGoします。
警告
ナビゲーションの改善が進行中
現在、新しく改良されたナビゲーション エクスペリエンスを導入中です。次の手順が Atlas UI の表示と一致しない場合は、プレビュー ドキュメントを参照してください。
まだ表示されていない場合は、希望するプロジェクトを含む組織を選択しますナビゲーション バーのOrganizationsメニュー
まだ表示されていない場合は、ナビゲーション バーのProjectsメニューから目的のプロジェクトを選択します。
まだ表示されていない場合は、サイドバーの [Clusters] をクリックします。
[ Clusters (クラスター) ] ページが表示されます。
インデックスの設定を開始します。
ページで次の選択を行い、Next をクリックしてください。
Search Type | Atlas Search のインデックスタイプを選択します。 |
Index Name and Data Source | 以下の情報を指定してください。
|
Configuration Method | For a guided experience, select Visual Editor. To edit the raw index definition, select JSON Editor. |
注意
Atlas Search インデックスのデフォルト名は「default
」です。この名前を変更しない場合、Atlas Search クエリのデフォルトの検索インデックスが使用され、その演算子では別の index
オプションは指定されません。複数のインデックスを作成する場合は、インデックス全体で一貫性があり、内容がわかる命名規則を維持することをお勧めします。
マテリアライズドビューでのクエリの実行
新しくアップデートされ、インデックスが作成されたmonthlyPhoneTransactions
コレクションに対してクエリを実行します。
mongosh
内のクラスターに接続します。
ターミナル ウィンドウでmongosh
を開き、クラスターに接続します。 接続の詳細な手順については、「 mongosh
経由での接続 」を参照してください。
sample_supplies
データベースを使用します。
mongosh
プロンプトで次のコマンドを実行します。
use sample_supplies
sample_supplies.monthlyPhoneTransactions
コレクションに対して簡単な Atlas Search クエリを実行します。
次のクエリは、合計売上額が10000
ドル以上の MongoDBTransactions の月数をカウントします。
db.monthlyPhoneTransactions.aggregate([ { $search: { "index": "monthlySalesIndex", "range": { "gt": 10000, "path": ["sales_price"] } } }, { $count: 'months_w_over_10000' }, ])
上記のクエリでは4
が返されます。これは、 monthlyPhoneTransactions
マテリアライズドビューのすべての月のうち4か月のみが合計売上額が10000ドル以上であったことを示します。 この結果は、sample_supplies.sales
sample_supplies.purchaseOrders
コレクションと コレクションの両方のデータを反映しています。
集計パイプラインの完全なドキュメントについては、 MongoDB Server マニュアル を参照してください。