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 演算子のいずれかを使用する必要があります。詳しくは、以下を参照してください。
Retrieve the Root Document 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 populates searchRootDocumentId only when your query sets both returnStoredSource: true and returnScope.path. If you reference searchRootDocumentId in a query that does not specify returnScope, the query fails with the following error:
query requires $search root document id metadata, but it is not available
Use searchRootDocumentId if you want to:
Fetch fields from the parent document after filtering on the child documents.
Group child documents by their parent.
Don't use searchRootDocumentId if:
You need only fields from the matched child documents.
You want to return the parent document for every child document in the result set, since this can be expensive.
例
以下の例はクエリで 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' } } ] } ]
The following query uses the range (MongoDB Search Operator) to query the funding_rounds.raised_amount field for amount greater than and equal to 5000000 and less than and equal to 10000000. It sets the query scope as funding_rounds field using the returnScope option. It groups the matching funding_rounds under each parent company by using the searchRootDocumentId meta field as the group key and computes the average raised_amount per company in the avgRaisedAmount field. It sorts the results by avgRaisedAmount in descending order and limits the number of results to 10 companies.
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 } ]
The following query uses the range (MongoDB Search Operator) to query the funding_rounds.raised_amount field for amount greater than and equal to 5000000 and less than and equal to 10000000. It sets the query scope as funding_rounds field using the returnScope option. It sorts the matching funding_rounds by raised_amount in descending order and limits the results to the top 10 funding rounds. It then uses the searchRootDocumentId meta field to join each funding round back to its parent company in the companies collection and returns the company's name alongside the funding round's round_code, raised_amount, and raised_currency_code fields.
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' } } ]