Puede utilizar el returnScope opción para establecer el contexto de la query y devolver arreglos de objetos como documentos individuales.
Requisitos
Para recuperar objetos anidados como documentos individuales usando returnScope, debes:
Indexe los arreglos de objetos como los tipo embeddedDocuments.
Define storedSource para los campos anidados que desees recuperar. MongoDB Search sólo devuelve los campos definidos en el
storedSource.Configure la opción returnStoredSource en
trueen la query.
Sintaxis
returnScope tiene la siguiente sintaxis en tus consultas:
Para obtener más información sobre la sintaxis de query, consulta $search.
Comportamiento
La opción returnScope establece el contexto de obtención para la query. Si especifica returnScope en su consulta, MongoDB Search otorga puntuación, ordena y cuenta cada documento incrustado como si se tratase de un documento individual.
Considerations
Cuando utilizas la opción returnScope, MongoDB Search solo devuelve los campos que configuraste como storedSource dentro del embeddedDocument. No se devuelven los campos fuera de la ruta embeddedDocument (por ejemplo, los campos a nivel de raíz) y los campos que no están configurados como storedSource.
En tu especificación de operador, debes especificar la ruta completa al campo que deseas query. Al usar la opción returnScope, debes asegurarte de que todas las rutas de especificaciones del operador estén anidadas debajo del returnScope.path. Para query sobre un campo fuera del returnScope.path, debe usar el operador hasAncestor o hasRoot. Para obtener más información, consulte:
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.
Ejemplos
Los siguientes ejemplos demuestran cómo utilizar la opción returnScope en las consultas. Los ejemplos utilizan el conjunto de datos de muestra sample_training.companies. Si cargas los datos en tu clúster y creas el índice de muestra en los campos de la colección, puedes probar las siguientes consultas con los datos de muestra.
Índice de muestra
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 }
La definición de índice anterior configura MongoDB Search para que:
Indexen los campos
funding_roundsyfunding_rounds.investmentscomo el tipoembeddedDocuments.Indiza todos los campos indexables de forma dinámica anidados en el arreglo de objetos
funding_roundsyfunding_rounds.investments.Almacena los siguientes campos en
mongot:funding_rounds.round_codefunding_rounds.raised_currency_codefunding_rounds.raised_amountfunding_rounds.investments.personfunding_rounds.investments.financial_org
Puedes utilizar el operador embeddedDocument para realizar queries por elementos en los campos funding_rounds y funding_rounds.investments. Las siguientes secciones muestran algunas consultas de ejemplo que utilizan la opción returnScope para recuperar los campos embeddedDocuments como documentos individuales.
{ ..., "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>" } }, ... ] }, ... ], ... }
Queries de muestra
Las siguientes secciones demuestran consultas de muestra que utilizan la opción returnScope para recuperar campos en campos de tipo embeddedDocuments que se almacenaron en mongot.
La siguiente query utiliza el range (MongoDB Search operador) para consultar el campo funding_rounds.raised_amount por una cantidad mayor o igual a 5000000 y menor o igual a 10000000. Establece el ámbito de consulta como el campo funding_rounds usando la opción returnScope. Devuelve todos los campos almacenados dentro del arreglo de objetos funding_rounds, incluyendo los campos en el arreglo de objetos funding_rounds.investments que se almacenaron utilizando la opción returnStoredSource. Limita el número de resultados a sólo 5 documentos 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 } ] } ]
La siguiente query utiliza el compound Operador para buscar varios niveles de campos embeddedDocuments anidados en la misma query:
Debe coincidir con ``funding_rounds.raised_currency_code`` con
USDDebe coincidir
funding_rounds.investments.financial_org.nameconTrinity Ventures
Devuelve todos los campos almacenados dentro del funding_rounds arreglo de objetos, incluyendo los campos en funding_rounds.investments. Limita el número de resultados a solo 5 funding_rounds documentos.
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' } } ]