returnScope オプションを使用してクエリのコンテキストを設定し、オブジェクトの配列を個別のドキュメントとして返すことができます。
要件
returnScopeを使用してネストされたオブジェクトを個別のドキュメントとして検索するには、次の手順が必要です。
オブジェクトの配列を embeddedDocuments 型としてインデックス化します。
検索するネストされたフィールドの storedSource を定義します。MongoDB Search は、
storedSourceで定義されているフィールドのみを返します。クエリで returnStoredSource オプションを
trueに設定します。
構文
returnScope クエリでは、次の構文を使用します。
クエリ構文の詳細については、 $searchを参照してください。
動作
returnScopeオプションはクエリの取得コンテキストを設定します。クエリで returnScope を指定すると、MongoDB Search は各埋め込みドキュメントを個別のドキュメントであるかのようにスコア付け、ソート、カウントします。
Considerations
returnScope オプションを使用すると、MongoDB Search は embeddedDocument 内で storedSource として設定したフィールドのみを返します。embeddedDocument パスの外側のフィールド(ルートレベルのフィールドなど)および storedSource として設定されていないフィールドは返されません。
演算子仕様では、クエリするフィールドへの完全なパスを指定する必要があります。returnScope オプションを使用する場合は、すべての演算子仕様パスが returnScope.path の下にネストされていることを確認する必要があります。returnScope.path 外のフィールドをクエリするには、hasAncestor 演算子または hasRoot 演算子のいずれかを使用する必要があります。詳しくは、以下を参照してください。
ルート ドキュメント ID を検索する
When you use returnScope in a query, MongoDB Search populates a searchRootDocumentId metadata field. You can use the searchRootDocumentId metadata field on clusters running MongoDB 8.3 or later. This field contains the identifier of the root document that contains each returned embedded document. To project this value, use the $meta expression with the searchRootDocumentId keyword.
MongoDB Search は、クエリでreturnStoredSource: trueとreturnScope.pathの両方を設定した場合にのみsearchRootDocumentIdを移入します。returnScopeを指定しないクエリでsearchRootDocumentIdを参照すると、クエリは次のエラーで失敗します。
query requires $search root document id metadata, but it is not available
次の場合は、searchRootDocumentId を使用します。
子ドキュメントでフィルターした後、親ドキュメントからフィールドを取得します。
子ドキュメントを親でグループ化します。
searchRootDocumentId を使用しない方がよい場合は次のとおりです。
一致する子ドキュメントからのフィールドのみが必要です。
これはコストが高くなる可能性があるため、結果セット内のすべての子ドキュメントに対して親ドキュメントを返す必要があります。
例
以下の例はクエリで returnScope オプションの使用方法を示しています。この例は sample_training.companies サンプルデータセットを使用します。クラスターにデータをロードし、コレクションのフィールドにサンプルインデックスを作成したら、サンプルデータに対して次のクエリを試すことができます。
サンプル インデックス
1 { 2 "mappings": { 3 "dynamic": false, 4 "fields": { 5 "funding_rounds": { 6 "type": "embeddedDocuments", 7 "dynamic": true, 8 "fields": { 9 "investments": { 10 "type": "embeddedDocuments", 11 "dynamic": true 12 } 13 }, 14 "storedSource": { 15 "include": [ 16 "round_code", 17 "raised_currency_code", 18 "raised_amount", 19 "investments.person", 20 "investments.financial_org" 21 ] 22 } 23 } 24 } 25 } 26 }
上記のインデックス定義により、 MongoDB Search は次のように構成されます。
funding_roundsフィールドとfunding_rounds.investmentsフィールドをembeddedDocuments型としてインデックスします。funding_roundsとfunding_rounds.investmentsのオブジェクト配列にネストされたすべての動的にインデックス可能なフィールドをインデックスします。mongotに以下のフィールドを保存します。funding_rounds.round_codefunding_rounds.raised_currency_codefunding_rounds.raised_amountfunding_rounds.investments.personfunding_rounds.investments.financial_org
embeddedDocument演算子を使用すると、 funding_roundsフィールドとfunding_rounds.investmentsフィールドの両方に対して要素ごとのクエリを実行できます。次のセクションでは、returnScopeオプションを使用してembeddedDocumentsフィールドを個別のドキュメントとして検索するいくつかのサンプルクエリを示します。
{ ..., "funding_rounds": [ { "id": <integer>, "round_code": "<string>", "source_url": "<string>", "source_description": "<string>", "raised_amount": <integer>, "raised_currency_code": "<string>", "funded_year": <integer>, "funded_month": "<string>", "funded_day": "<string>", "investments": [ { "company": "<string>", "financial_org": { "name": "<string>", "permalink": "<string>" }, "person": { "first_name": "<string>", "last_name": "<string>", "permalink": "<string>" } }, ... ] }, ... ], ... }
サンプル クエリ
以下のセクションでは、returnScope オプションを使用してembeddedDocuments mongot型のフィールドで保存されたフィールドを検索するサンプルクエリを示します。
次のクエリでは、range(MongoDB 検索演算子)を使用して、funding_rounds.raised_amountフィールドに対して、5000000 以上かつ 10000000 以下の値をクエリします。returnScope オプションを使用して、クエリ スコープを funding_roundsフィールドに設定します。returnStoredSource オプションを使用して保存されたオブジェクトの funding_rounds.investments 配列内のフィールドを含む、オブジェクトの funding_rounds 配列内に保存されたすべてのフィールドが返されます。結果数を 5 funding_rounds ドキュメントのみに制限します。
1 db.companies.aggregate( 2 { 3 "$search": { 4 "range": { 5 "path": "funding_rounds.raised_amount", 6 "gte": 5000000, 7 "lte": 10000000 8 }, 9 "returnStoredSource": true, 10 "returnScope": { 11 "path": "funding_rounds" 12 } 13 } 14 }, 15 { 16 "$limit": 5 17 } 18 )
[ { round_code: 'a', raised_amount: 5250000, raised_currency_code: 'USD', investments: [ { financial_org: { name: 'Frazier Technology Ventures', permalink: 'frazier-technology-ventures' }, person: null }, { financial_org: { name: 'Trinity Ventures', permalink: 'trinity-ventures' }, person: null } ] }, { round_code: 'b', raised_amount: 9500000, raised_currency_code: 'USD', investments: [ { financial_org: { name: 'Accel Partners', permalink: 'accel-partners' }, person: null }, { financial_org: { name: 'Frazier Technology Ventures', permalink: 'frazier-technology-ventures' }, person: null }, { financial_org: { name: 'Trinity Ventures', permalink: 'trinity-ventures' }, person: null } ] }, { round_code: 'a', raised_amount: 5000000, raised_currency_code: 'USD', investments: [ { financial_org: { name: 'Charles River Ventures', permalink: 'charles-river-ventures' }, person: null }, { financial_org: { name: 'Union Square Ventures', permalink: 'union-square-ventures' }, person: null }, { financial_org: null, person: { first_name: 'Marc', last_name: 'Andreessen', permalink: 'marc-andreessen' } }, { financial_org: null, person: { first_name: 'Dick', last_name: 'Costolo', permalink: 'dick-costolo' } }, { financial_org: null, person: { first_name: 'Naval', last_name: 'Ravikant', permalink: 'naval-ravikant' } }, { financial_org: null, person: { first_name: 'Ron', last_name: 'Conway', permalink: 'ron-conway' } }, { financial_org: null, person: { first_name: 'Chris', last_name: 'Sacca', permalink: 'chris-sacca' } }, { financial_org: null, person: { first_name: 'Greg', last_name: 'Yaitanes', permalink: 'greg-yaitanes' } }, { financial_org: null, person: { first_name: 'Brian', last_name: 'Pokorny', permalink: 'brian-pokorny' } }, { financial_org: { name: 'SV Angel', permalink: 'sv-angel' }, person: null } ] }, { round_code: 'e', raised_amount: 5166511, raised_currency_code: 'USD', investments: [] }, { round_code: 'b', raised_amount: 9000000, raised_currency_code: 'USD', investments: [ { financial_org: { name: 'Charles River Ventures', permalink: 'charles-river-ventures' }, person: null }, { financial_org: { name: 'Redpoint Ventures', permalink: 'redpoint-ventures' }, person: null }, { financial_org: { name: 'The Kinsey Hills Group', permalink: 'kinsey-hills-group' }, person: null } ] } ]
次のクエリでは、compound演算子を使用して、同じクエリ内のネストされたembeddedDocumentsフィールドの複数レベルを検索します。
「funding_rounds.raised_currency_code」は次と一致する必要があります。
USDfunding_rounds.investments.financial_org.nameとTrinity Venturesは一致する必要があります
funding_rounds オブジェクトの配列内のすべての保存されたフィールドを返します。これには、funding_rounds.investments 内のフィールドも含まれます。結果の数は 5 funding_rounds ドキュメントに制限されます。
1 db.companies.aggregate( 2 { 3 "$search": { 4 "compound": { 5 "must": [{ 6 "text": { 7 "path": "funding_rounds.raised_currency_code", 8 "query": "usd" 9 } 10 }], 11 "should": [{ 12 "phrase": { 13 "path": "funding_rounds.investments.financial_org", 14 "query": "Trinity Ventures", 15 } 16 }] 17 }, 18 "returnStoredSource": true, 19 "returnScope": { 20 "path": "funding_rounds" 21 } 22 } 23 }, 24 { 25 "$limit": 5 26 } 27 )
[ { round_code: 'a', raised_amount: 5250000, raised_currency_code: 'USD', investments: [ { financial_org: { name: 'Frazier Technology Ventures', permalink: 'frazier-technology-ventures' }, person: null }, { financial_org: { name: 'Trinity Ventures', permalink: 'trinity-ventures' }, person: null } ] }, { round_code: 'b', raised_amount: 9500000, raised_currency_code: 'USD', investments: [ { financial_org: { name: 'Accel Partners', permalink: 'accel-partners' }, person: null }, { financial_org: { name: 'Frazier Technology Ventures', permalink: 'frazier-technology-ventures' }, person: null }, { financial_org: { name: 'Trinity Ventures', permalink: 'trinity-ventures' }, person: null } ] }, { round_code: 'c', raised_amount: 25000000, raised_currency_code: 'USD', investments: [ { financial_org: { name: 'DAG Ventures', permalink: 'dag-ventures' }, person: null }, { financial_org: { name: 'Accel Partners', permalink: 'accel-partners' }, person: null }, { financial_org: { name: 'Trinity Ventures', permalink: 'trinity-ventures' }, person: null }, { financial_org: { name: 'Frazier Technology Ventures', permalink: 'frazier-technology-ventures' }, person: null } ] }, { round_code: 'angel', raised_amount: 500000, raised_currency_code: 'USD', investments: [ { financial_org: null, person: { first_name: 'Peter', last_name: 'Thiel', permalink: 'peter-thiel' } }, { financial_org: null, person: { first_name: 'Reid', last_name: 'Hoffman', permalink: 'reid-hoffman' } } ] }, { round_code: 'a', raised_amount: 12700000, raised_currency_code: 'USD', investments: [ { financial_org: { name: 'Accel Partners', permalink: 'accel-partners' }, person: null }, { financial_org: null, person: { first_name: 'Mark', last_name: 'Pincus', permalink: 'mark-pincus' } }, { financial_org: null, person: { first_name: 'Reid', last_name: 'Hoffman', permalink: 'reid-hoffman' } } ] } ]
次のクエリでは、range (MongoDB Search 演算子) を使用して、funding_rounds.raised_amount フィールドで金額が 5000000 以上 10000000 以下のものをクエリします。returnScope オプションを使用して、クエリスコープを funding_rounds フィールドとして設定します。searchRootDocumentId メタフィールドをグループ キーとして使用し、一致する funding_rounds を各親会社の下にグループ化し、avgRaisedAmount フィールドで会社ごとの平均 raised_amount を計算します。結果を avgRaisedAmount で降順にソートし、結果の数を 10 社に制限します。
1 db.companies.aggregate([ 2 { 3 "$search": { 4 "returnStoredSource": true, 5 "returnScope": { 6 "path": "funding_rounds" 7 }, 8 "range": { 9 "path": "funding_rounds.raised_amount", 10 "gte": 5000000, 11 "lte": 10000000 12 } 13 } 14 }, 15 { 16 "$group": { 17 "_id": { "$meta": "searchRootDocumentId" }, 18 "funding_rounds": { 19 "$push": { 20 "round_code": "$round_code", 21 "raised_amount": "$raised_amount", 22 "raised_currency_code": "$raised_currency_code" 23 } 24 }, 25 "avgRaisedAmount": { "$avg": "$raised_amount" } 26 } 27 }, 28 { "$sort": { "avgRaisedAmount": -1 } }, 29 { "$limit": 10 } 30 ])
[ { _id: ObjectId('52cdef7d4bab8bd675298f82'), funding_rounds: [ { round_code: 'a', raised_amount: 10000000, raised_currency_code: 'USD' } ], avgRaisedAmount: 10000000 }, { _id: ObjectId('52cdef7e4bab8bd67529af80'), funding_rounds: [ { round_code: 'b', raised_amount: 10000000, raised_currency_code: 'USD' } ], avgRaisedAmount: 10000000 }, { _id: ObjectId('52cdef7f4bab8bd67529be3d'), funding_rounds: [ { round_code: 'a', raised_amount: 10000000, raised_currency_code: 'USD' } ], avgRaisedAmount: 10000000 }, { _id: ObjectId('52cdef7f4bab8bd67529c52d'), funding_rounds: [ { round_code: 'unattributed', raised_amount: 10000000, raised_currency_code: 'USD' } ], avgRaisedAmount: 10000000 }, { _id: ObjectId('52cdef7e4bab8bd67529ab31'), funding_rounds: [ { round_code: 'c', raised_amount: 10000000, raised_currency_code: 'USD' }, { round_code: 'a', raised_amount: 10000000, raised_currency_code: 'USD' } ], avgRaisedAmount: 10000000 }, { _id: ObjectId('52cdef7e4bab8bd67529aa94'), funding_rounds: [ { round_code: 'b', raised_amount: 10000000, raised_currency_code: 'USD' } ], avgRaisedAmount: 10000000 }, { _id: ObjectId('52cdef7f4bab8bd67529be6f'), funding_rounds: [ { round_code: 'a', raised_amount: 10000000, raised_currency_code: 'USD' } ], avgRaisedAmount: 10000000 }, { _id: ObjectId('52cdef7c4bab8bd6752985cb'), funding_rounds: [ { round_code: 'd', raised_amount: 10000000, raised_currency_code: 'USD' } ], avgRaisedAmount: 10000000 }, { _id: ObjectId('52cdef7d4bab8bd675299fd1'), funding_rounds: [ { round_code: 'c', raised_amount: 10000000, raised_currency_code: 'USD' } ], avgRaisedAmount: 10000000 }, { _id: ObjectId('52cdef7f4bab8bd67529c2c8'), funding_rounds: [ { round_code: 'debt_round', raised_amount: 10000000, raised_currency_code: 'USD' } ], avgRaisedAmount: 10000000 } ]
次のクエリでは、range (MongoDB Search 演算子)を使用して、funding_rounds.raised_amountフィールドに対して、5000000 以上かつ 10000000 未満の値をクエリします。returnScope オプションを使用して、クエリ スコープを funding_roundsフィールドに設定します。一致する funding_rounds を raised_amount で降順にソートし、結果を上位の 10 ファジー ラウンドに制限します。次に、searchRootDocumentId メタフィールドを使用して各関数ラウンドを companiesコレクション内の会社に結合し、会社の name とファジーメント ラウンドの round_code、raised_amount、raised_currency_code フィールドを返します。
1 db.companies.aggregate([ 2 { 3 "$search": { 4 "returnStoredSource": true, 5 "returnScope": { 6 "path": "funding_rounds" 7 }, 8 "range": { 9 "path": "funding_rounds.raised_amount", 10 "gte": 5000000, 11 "lte": 10000000 12 } 13 } 14 }, 15 { "$sort": { "raised_amount": -1 } }, 16 { "$limit": 10 }, 17 { "$addFields": { "root_id": { "$meta": "searchRootDocumentId" } } }, 18 { 19 "$lookup": { 20 "from": "companies", 21 "localField": "root_id", 22 "foreignField": "_id", 23 "as": "company" 24 } 25 }, 26 { "$unwind": "$company" }, 27 { 28 "$project": { 29 "_id": 0, 30 "round_code": 1, 31 "raised_amount": 1, 32 "raised_currency_code": 1, 33 "company.name": 1 34 } 35 } 36 ])
[ { round_code: 'partial', raised_amount: 10000000, raised_currency_code: 'USD', company: { name: 'WeFi' } }, { round_code: 'b', raised_amount: 10000000, raised_currency_code: 'USD', company: { name: 'LinkedIn' } }, { round_code: 'a', raised_amount: 10000000, raised_currency_code: 'USD', company: { name: 'Lotame' } }, { round_code: 'c', raised_amount: 10000000, raised_currency_code: 'USD', company: { name: 'OpenX' } }, { round_code: 'b', raised_amount: 10000000, raised_currency_code: 'USD', company: { name: 'AddThis' } }, { round_code: 'a', raised_amount: 10000000, raised_currency_code: 'USD', company: { name: 'Terabitz' } }, { round_code: 'b', raised_amount: 10000000, raised_currency_code: 'USD', company: { name: 'Six Apart' } }, { round_code: 'a', raised_amount: 10000000, raised_currency_code: 'USD', company: { name: 'Snocap' } }, { round_code: 'b', raised_amount: 10000000, raised_currency_code: 'USD', company: { name: 'Wikia' } }, { round_code: 'unattributed', raised_amount: 10000000, raised_currency_code: 'USD', company: { name: 'Mashery' } } ]