Docs Menu
Docs Home
/
MongoDB Atlas
/ / /

Atlas Search$search クエリを使用して $unionWith を実行する方法

項目一覧

  • Atlas Search インデックスの作成
  • $search $unionWithを実行し、コレクションを検索します

v6.0 以降、MongoDB$unionWith 集計ステージは、$search オプション内で$unionWithpipeline をサポートします。$unionWithを使用すると、結果セット内の同じデータベース内の複数のコレクションからの$searchの結果を組み合わせることができます。

このチュートリアルでは、 データベース内の コレクションと コレクションに対して、 を使用して クエリを実行する方法を説明します。$unionWith$searchcompaniesinspectionssample_training次の手順が必要です。

  1. データベース内の コレクションと コレクションの 動的マッピング を含む Atlas Search インデックスを設定します。companiesinspectionssample_training

  2. を使用して クエリを実行し、 コレクションから名前に $unionWithが含まれる会社と、$search コレクション内の同じまたは類似のビジネス名を持つ会社の和集合を実行します。mobilecompaniesinspections

開始する前に、Atlas クラスターが前提条件 に記載されている要件を満たしていることを確認してください。

注意

$unionWith$searchを使用して クエリを実行するには、クラスターで MongoDB v6.0 以上を実行する必要があります。

Atlas Search インデックスを作成するには、プロジェクトに対するProject Data Access Admin以上のアクセス権が必要です。

このセクションでは、 sample_trainingデータベースのcompaniesコレクション内のすべてのフィールドにdefaultという名前の Atlas Search インデックスを作成します。 sample_trainingデータベース内のinspectionsコレクションのすべてのフィールドに、 defaultという名前の別の Atlas Search インデックスを作成します。 コレクションごとに次の手順を実行する必要があります。

1
  1. まだ表示されていない場合は、希望するプロジェクトを含む組織を選択しますナビゲーション バーのOrganizationsメニュー

  2. まだ表示されていない場合は、ナビゲーション バーのProjectsメニューから目的のプロジェクトを選択します。

  3. まだ表示されていない場合は、サイドバーの [Clusters] をクリックします。

    [ Clusters (クラスター) ] ページが表示されます。

2

GoAtlas Searchページには、サイドバー、Data Explorer 、またはクラスターの詳細ページから できます。

  1. サイドバーで、 Services見出しの下のAtlas Searchをクリックします。

  2. [ Select data sourceドロップダウンからクラスターを選択し、[ Go to Atlas Search ] をクリックします。

    Atlas Searchページが表示されます。

  1. クラスターの [Browse Collections] ボタンをクリックします。

  2. データベースを展開し、コレクションを選択します。

  3. コレクションのSearch Indexesタブをクリックします。

    Atlas Searchページが表示されます。

  1. クラスタの名前をクリックします。

  2. [Atlas Search] タブをクリックします。

    Atlas Searchページが表示されます。

3

[Create Search Index] をクリックします。

4
  • ガイドを利用する場合は、Atlas Search Visual Editor を選択します。

  • Raw インデックス定義を編集するには、Atlas Search JSON Editor を選択します。

5
  1. Index Nameフィールドにdefaultと入力します。

    インデックスにdefaultと名付けると、 $searchパイプライン ステージでindexパラメータを指定する必要がなくなります。 インデックスにカスタム名を付ける場合は、 indexパラメータでこの名前を指定する必要があります。

  2. Database and Collectionセクションで、 sample_trainingデータベースを検索し、 コレクションを選択します。

    • companiesコレクションのインデックスを作成するには、 companiesを選択します。

    • inspectionsコレクションのインデックスを作成するには、 inspectionsを選択します。

6

次のインデックス定義は、コレクション内のサポートされている型のフィールドを動的にインデックス化します。 インデックスを作成するには、 インターフェースで または を使用できます。Atlas SearchVisual EditorAtlas SearchJSON EditorAtlas user

  1. [Next] をクリックします。

  2. コレクションの"default"インデックス定義を確認します。

  1. [Next] をクリックします。

  2. インデックスの定義を確認します。

    インデックス定義は、次の例のようになります。

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

インデックスが作成中であることを知らせるモーダル ウィンドウが表示されます。 [ Close ] ボタンをクリックします。

9

インデックスの構築には約 1 分かかります。 作成している間、 Status列にはBuild in Progressと表示されます。 作成が完了すると、 Status列にはActiveと表示されます。


➤ [言語の選択]ドロップダウン メニューを使用して、このセクション内の例の言語を設定します。


このセクションでは、Atlas クラスターに接続し、 sample_trainingデータベース内のインデックス作成されたコレクションに対してサンプル クエリを実行します。

1

ターミナル ウィンドウでmongoshを開き、クラスターに接続します。 接続の詳細な手順については、「 mongosh経由での接続 」を参照してください。

2

mongoshプロンプトで次のコマンドを実行します。

use sample_training
switched to db sample_training
3

次のクエリは、companies inspectionsmobilenameコレクションとbusiness_name コレクションの両方で、それぞれ フィールドと フィールドで というタームを検索します。

このクエリでは、次のステージを使用します。

  • $searchは、名前にmobileが含まれる会社を検索します。

  • $unionWith 必要に応じて、次の操作を実行します。

    • サブパイプラインの$searchステージを使用して、名前にmobileが含まれる会社の検査を検索します。

    • コレクションとcompanies inspectionsコレクションのドキュメントの和集合を実行します。

  • $setステージで、出力ドキュメントのコレクションを識別するsourceという名前の新しいフィールドを追加します。

    • $limitステージを使用して、各コレクションからの出力を3の結果に制限します。

    • $project stageを次のように設定します。

      • 指定されたフィールドのみを結果に含めます。

      • scoreという名前のフィールドを追加します。

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

このクエリでは、次のステージを使用します。

  • $searchは、名前にmobileが含まれる会社を検索します。

  • $project 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") }
]
}
]
1

MongoDB Compass を開き、クラスターに接続します。 接続の詳細な手順については、「 Compass 経由での接続 」を参照してください。

2

Database画面で、 sample_trainingデータベースをクリックし、 companiesコレクションをクリックします。

3

次のクエリは、companies inspectionsmobilenameコレクションとbusiness_name コレクションの両方で、それぞれ フィールドと フィールドで というタームを検索します。

MongoDB Compass でこのクエリを実行するには:

  1. [Aggregations] タブをクリックします。

  2. Select...をクリックし、ドロップダウンからステージを選択し、そのステージのクエリを追加して、次の各パイプライン ステージを構成します。 ステージを追加するには、 Add Stageをクリックします。

    このクエリでは、次のステージを使用します。

    • $searchは、名前にmobileが含まれる会社を検索します。

    • $unionWith 必要に応じて、次の操作を実行します。

      • サブパイプラインの$searchステージを使用して、名前にmobileが含まれる会社の検査を検索します。

      • コレクションとcompanies inspectionsコレクションのドキュメントの和集合を実行します。

    • $setステージで、出力ドキュメントのコレクションを識別するsourceという名前の新しいフィールドを追加します。

      • $limitステージを使用して、各コレクションからの出力を3の結果に制限します。

      • $project stageを次のように設定します。

        • 指定されたフィールドのみを結果に含めます。

        • scoreという名前のフィールドを追加します。

    パイプラインステージ
    クエリ

    $search

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

    $project

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

    $set

    {
    "source": "companies"
    }

    $limit

    3

    $unionWith

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

    Auto Preview有効にした場合、MongoDB Compass は$projectパイプライン ステージの横に次のドキュメントを表示します。

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

    このクエリでは、次のステージを使用します。

    • $searchは、名前にmobileが含まれる会社を検索します。

    • $project 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
4

MongoDB Compass では、結果で返されるドキュメントの、オブジェクト内のすべてのフィールドと配列内のすべての値が表示されない場合があります。 すべてのフィールドと値を表示するには、結果内の フィールドを展開します。

1
  1. search-with-unionwith という新しいディレクトリを作成し、dotnet new コマンドでプロジェクトを初期化します。

    mkdir search-with-unionwith
    cd search-with-unionwith
    dotnet new console
  2. .NET/C# ドライバーを依存関係としてプロジェクトに追加します。

    dotnet add package MongoDB.Driver
2

次のクエリは、companies inspectionsmobilenameコレクションとbusiness_name コレクションの両方で、それぞれ フィールドと フィールドで というタームを検索します。

このクエリでは、次のステージを使用します。

  • $searchは、名前にmobileが含まれる会社を検索します。

  • $unionWith 必要に応じて、次の操作を実行します。

    • サブパイプラインの$searchステージを使用して、名前にmobileが含まれる会社の検査を検索します。

    • コレクションとcompanies inspectionsコレクションのドキュメントの和集合を実行します。

  • $setステージで、出力ドキュメントのコレクションを識別するsourceという名前の新しいフィールドを追加します。

    • $limitステージを使用して、各コレクションからの出力を3の結果に制限します。

    • $project stageを次のように設定します。

      • 指定されたフィールドのみを結果に含めます。

      • scoreという名前のフィールドを追加します。

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

このクエリでは、次のステージを使用します。

  • $searchは、名前にmobileが含まれる会社を検索します。

  • $project stageを次のように設定します。

    • 指定されたフィールドのみを結果に含めます。

    • scoreという名前のフィールドを追加します。

  • $addFields ステージでは、次の新しいフィールドを追加します。

    • 出力ドキュメントのコレクションを識別するsourceという名前の新しいフィールド。

    • 出力ドキュメント数を示すフィールド名source_count

  • $unionWith 必要に応じて、次の操作を実行します。

    • サブパイプラインの$searchステージを使用して、名前にmobileが含まれる会社の検査を検索します。

    • コレクションとcompanies inspectionsコレクションのドキュメントの和集合を実行します。

  • $project stageを次のように設定します。

    • 指定されたフィールドのみを結果に含めます。

    • scoreという名前のフィールドを追加します。

  • $limitステージを使用して、各コレクションからの出力を3の結果に制限します。

  • $set ステージでは、次の新しいフィールドを追加します。

    • 出力ドキュメントのコレクションを識別するsourceという名前の新しいフィールド。

    • 出力ドキュメント数を表示するsource_countという名前の新しいフィールド。

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

接続stringにデータベースユーザーの認証情報が含まれていることを確認します。 詳しくは、「ドライバーによる接続 」を参照してください。

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

次のクエリは、companies inspectionsmobilenameコレクションとbusiness_name コレクションの両方で、それぞれ フィールドと フィールドで というタームを検索します。

このクエリでは、次のステージを使用します。

  • $searchは、名前にmobileが含まれる会社を検索します。

  • $unionWith 必要に応じて、次の操作を実行します。

    • サブパイプラインの$searchステージを使用して、名前にmobileが含まれる会社の検査を検索します。

    • コレクションとcompanies inspectionsコレクションのドキュメントの和集合を実行します。

  • $setステージで、出力ドキュメントのコレクションを識別するsourceという名前の新しいフィールドを追加します。

    • $limitステージを使用して、各コレクションからの出力を3の結果に制限します。

    • $project stageを次のように設定します。

      • 指定されたフィールドのみを結果に含めます。

      • scoreという名前のフィールドを追加します。

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

このクエリでは、次のステージを使用します。

  • $searchは、名前にmobileが含まれる会社を検索します。

  • $project stageを次のように設定します。

    • 指定されたフィールドのみを結果に含めます。

    • scoreという名前のフィールドを追加します。

  • $addFields ステージでは、次の新しいフィールドを追加します。

    • 出力ドキュメントのコレクションを識別するsourceという名前の新しいフィールド。

    • 出力ドキュメント数を示すフィールド名source_count

  • $unionWith 必要に応じて、次の操作を実行します。

    • サブパイプラインの$searchステージを使用して、名前にmobileが含まれる会社の検査を検索します。

    • コレクションとcompanies inspectionsコレクションのドキュメントの和集合を実行します。

  • $project stageを次のように設定します。

    • 指定されたフィールドのみを結果に含めます。

    • scoreという名前のフィールドを追加します。

  • $limitステージを使用して、各コレクションからの出力を3の結果に制限します。

  • $set ステージでは、次の新しいフィールドを追加します。

    • 出力ドキュメントのコレクションを識別するsourceという名前の新しいフィールド。

    • 出力ドキュメント数を表示するsource_countという名前の新しいフィールド。

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

接続stringにデータベースユーザーの認証情報が含まれていることを確認します。 詳しくは、「ドライバーによる接続 」を参照してください。

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

junit

4.11以降のバージョン

mongodb-driver-sync

4.3.0以降のバージョン

slf4j-log4j12

1.7.30以降のバージョン

2
3

次のクエリは、companies inspectionsmobilenameコレクションとbusiness_name コレクションの両方で、それぞれ フィールドと フィールドで というタームを検索します。

このクエリでは、次のステージを使用します。

  • $searchは、名前にmobileが含まれる会社を検索します。

  • $unionWith 必要に応じて、次の操作を実行します。

    • サブパイプラインの$searchステージを使用して、名前にmobileが含まれる会社の検査を検索します。

    • コレクションとcompanies inspectionsコレクションのドキュメントの和集合を実行します。

  • $setステージで、出力ドキュメントのコレクションを識別するsourceという名前の新しいフィールドを追加します。

    • $limitステージを使用して、各コレクションからの出力を3の結果に制限します。

    • $project stageを次のように設定します。

      • 指定されたフィールドのみを結果に含めます。

      • scoreという名前のフィールドを追加します。

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

このクエリでは、次のステージを使用します。

  • $searchは、名前にmobileが含まれる会社を検索します。

  • $project stageを次のように設定します。

    • 指定されたフィールドのみを結果に含めます。

    • scoreという名前のフィールドを追加します。

  • $addFields ステージでは、次の新しいフィールドを追加します。

    • 出力ドキュメントのコレクションを識別するsourceという名前の新しいフィールド。

    • 出力ドキュメント数を示すフィールド名source_count

  • $unionWith 必要に応じて、次の操作を実行します。

    • サブパイプラインの$searchステージを使用して、名前にmobileが含まれる会社の検査を検索します。

    • コレクションとcompanies inspectionsコレクションのドキュメントの和集合を実行します。

  • $project stageを次のように設定します。

    • 指定されたフィールドのみを結果に含めます。

    • scoreという名前のフィールドを追加します。

  • $limitステージを使用して、各コレクションからの出力を3の結果に制限します。

  • $set ステージでは、次の新しいフィールドを追加します。

    • 出力ドキュメントのコレクションを識別するsourceという名前の新しいフィールド。

    • 出力ドキュメント数を表示するsource_countという名前の新しいフィールド。

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

注意

Maven 環境でサンプル コードを実行するには、 ファイルのインポート ステートメントの上に次のコードを追加します。

package com.mongodb.drivers;
4

接続stringにデータベースユーザーの認証情報が含まれていることを確認します。 詳しくは、「ドライバーによる接続 」を参照してください。

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

mongodb-driver-kotlin-coroutine

4.10.0以降のバージョン

2
3

次のクエリは、companies inspectionsmobilenameコレクションとbusiness_name コレクションの両方で、それぞれ フィールドと フィールドで というタームを検索します。

このクエリでは、次のステージを使用します。

  • $searchは、名前にmobileが含まれる会社を検索します。

  • $unionWith 必要に応じて、次の操作を実行します。

    • サブパイプラインの$searchステージを使用して、名前にmobileが含まれる会社の検査を検索します。

    • コレクションとcompanies inspectionsコレクションのドキュメントの和集合を実行します。

  • $setステージで、出力ドキュメントのコレクションを識別するsourceという名前の新しいフィールドを追加します。

    • $limitステージを使用して、各コレクションからの出力を3の結果に制限します。

    • $project stageを次のように設定します。

      • 指定されたフィールドのみを結果に含めます。

      • scoreという名前のフィールドを追加します。

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

このクエリでは、次のステージを使用します。

  • $searchは、名前にmobileが含まれる会社を検索します。

  • $project stageを次のように設定します。

    • 指定されたフィールドのみを結果に含めます。

    • scoreという名前のフィールドを追加します。

  • $addFields ステージでは、次の新しいフィールドを追加します。

    • 出力ドキュメントのコレクションを識別するsourceという名前の新しいフィールド。

    • 出力ドキュメント数を示すフィールド名source_count

  • $unionWith 必要に応じて、次の操作を実行します。

    • サブパイプラインの$searchステージを使用して、名前にmobileが含まれる会社の検査を検索します。

    • コレクションとcompanies inspectionsコレクションのドキュメントの和集合を実行します。

  • $project stageを次のように設定します。

    • 指定されたフィールドのみを結果に含めます。

    • scoreという名前のフィールドを追加します。

  • $limitステージを使用して、各コレクションからの出力を3の結果に制限します。

  • $set ステージでは、次の新しいフィールドを追加します。

    • 出力ドキュメントのコレクションを識別するsourceという名前の新しいフィールド。

    • 出力ドキュメント数を表示するsource_countという名前の新しいフィールド。

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

接続stringにデータベースユーザーの認証情報が含まれていることを確認します。 詳しくは、「ドライバーによる接続 」を参照してください。

5

IDE でSearchWithUnionwithQuery.ktプログラムを実行すると、次のドキュメントが出力されます。

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

IDE でSearchWithUnionwithQuery.ktプログラムを実行すると、次の結果が出力されます。

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

次のクエリは、companies inspectionsmobilenameコレクションとbusiness_name コレクションの両方で、それぞれ フィールドと フィールドで というタームを検索します。

このクエリでは、次のステージを使用します。

  • $searchは、名前にmobileが含まれる会社を検索します。

  • $unionWith 必要に応じて、次の操作を実行します。

    • サブパイプラインの$searchステージを使用して、名前にmobileが含まれる会社の検査を検索します。

    • コレクションとcompanies inspectionsコレクションのドキュメントの和集合を実行します。

  • $setステージで、出力ドキュメントのコレクションを識別するsourceという名前の新しいフィールドを追加します。

    • $limitステージを使用して、各コレクションからの出力を3の結果に制限します。

    • $project stageを次のように設定します。

      • 指定されたフィールドのみを結果に含めます。

      • scoreという名前のフィールドを追加します。

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

このクエリでは、次のステージを使用します。

  • $searchは、名前にmobileが含まれる会社を検索します。

  • $project stageを次のように設定します。

    • 指定されたフィールドのみを結果に含めます。

    • scoreという名前のフィールドを追加します。

  • $addFields ステージでは、次の新しいフィールドを追加します。

    • 出力ドキュメントのコレクションを識別するsourceという名前の新しいフィールド。

    • 出力ドキュメント数を示すフィールド名source_count

  • $unionWith 必要に応じて、次の操作を実行します。

    • サブパイプラインの$searchステージを使用して、名前にmobileが含まれる会社の検査を検索します。

    • コレクションとcompanies inspectionsコレクションのドキュメントの和集合を実行します。

  • $project stageを次のように設定します。

    • 指定されたフィールドのみを結果に含めます。

    • scoreという名前のフィールドを追加します。

  • $limitステージを使用して、各コレクションからの出力を3の結果に制限します。

  • $set ステージでは、次の新しいフィールドを追加します。

    • 出力ドキュメントのコレクションを識別するsourceという名前の新しいフィールド。

    • 出力ドキュメント数を表示するsource_countという名前の新しいフィールド。

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

接続stringにデータベースユーザーの認証情報が含まれていることを確認します。 詳しくは、「ドライバーによる接続 」を参照してください。

4

次のコマンドを実行して、コレクションをクエリします。

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

次のクエリは、companies inspectionsmobilenameコレクションとbusiness_name コレクションの両方で、それぞれ フィールドと フィールドで というタームを検索します。

このクエリでは、次のステージを使用します。

  • $searchは、名前にmobileが含まれる会社を検索します。

  • $unionWith 必要に応じて、次の操作を実行します。

    • サブパイプラインの$searchステージを使用して、名前にmobileが含まれる会社の検査を検索します。

    • コレクションとcompanies inspectionsコレクションのドキュメントの和集合を実行します。

  • $setステージで、出力ドキュメントのコレクションを識別するsourceという名前の新しいフィールドを追加します。

    • $limitステージを使用して、各コレクションからの出力を3の結果に制限します。

    • $project stageを次のように設定します。

      • 指定されたフィールドのみを結果に含めます。

      • scoreという名前のフィールドを追加します。

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

このクエリでは、次のステージを使用します。

  • $searchは、名前にmobileが含まれる会社を検索します。

  • $project stageを次のように設定します。

    • 指定されたフィールドのみを結果に含めます。

    • scoreという名前のフィールドを追加します。

  • $addFields ステージでは、次の新しいフィールドを追加します。

    • 出力ドキュメントのコレクションを識別するsourceという名前の新しいフィールド。

    • 出力ドキュメント数を示すフィールド名source_count

  • $unionWith 必要に応じて、次の操作を実行します。

    • サブパイプラインの$searchステージを使用して、名前にmobileが含まれる会社の検査を検索します。

    • コレクションとcompanies inspectionsコレクションのドキュメントの和集合を実行します。

  • $project stageを次のように設定します。

    • 指定されたフィールドのみを結果に含めます。

    • scoreという名前のフィールドを追加します。

  • $limitステージを使用して、各コレクションからの出力を3の結果に制限します。

  • $set ステージでは、次の新しいフィールドを追加します。

    • 出力ドキュメントのコレクションを識別するsourceという名前の新しいフィールド。

    • 出力ドキュメント数を表示するsource_countという名前の新しいフィールド。

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

接続stringにデータベースユーザーの認証情報が含まれていることを確認します。 詳しくは、「ドライバーによる接続 」を参照してください。

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

戻る

$lookup と $search