MCPcopy Create free account
hub / github.com/documentdb/documentdb / BsonUnwindElement

Function BsonUnwindElement

pg_documentdb/src/aggregation/bson_unwind.c:397–485  ·  view source on GitHub ↗

* BsonUnwindElement produces the output document when element * at the unwind target * document -> source document * path -> path being unwound * indexFieldName -> optional name for the index field to be added * element -> the value found at the unwind target */

Source from the content-addressed store, hash-verified

395 * element -> the value found at the unwind target
396 */
397static pgbson *
398BsonUnwindElement(pgbson *document, char *path, char *indexFieldName, long index, const
399 bson_value_t *element)
400{
401 /*
402 * Document: { "a" : [ 1, [1,2], { "c": "value"}, "x"] }
403 * Unwind Spec: { "$unwind" : "a" }
404 *
405 * Expected Result: { "a" : 1}
406 * { "a" : [1,2] }
407 * { "a" : { "c": "value"} }
408 * { "a" : "x" }
409 *
410 * This is achieved by performing AddFields() 4 times on the original source document
411 * using the following 4 AddFields spec. Basically, we replace the array path with the
412 * elements of the array.
413 * 1. {"addFields" : { "a" : 1}}
414 * 2. {"addFields" : { "a" : [1,2] }}
415 * 3. {"addFields" : { "a" : { "c": "value"} }}
416 * 4. {"addFields" : { "a" : "x" }}
417 *
418 * We also, instruct the addFields spec to treat the elemnts to be the final value without
419 * any need for recursive expression evaluation.
420 *
421 * Note: All other fields in the document (not shown here) gets projected as it is.
422 *
423 */
424
425 BsonIntermediatePathNode *root = MakeRootNode();
426
427 /* unwound elements come from arrays in documents which will already be evaluated in a previous stage or directly from a collection, */
428 /* so we can safely treat the values as constants and no need to pay the cost to parse them as expressions. */
429 bool treatLeafDataAsConstant = true;
430 ParseAggregationExpressionContext parseContext = { 0 };
431
432 /* Create the node for unwound element */
433 if (element->value_type != BSON_TYPE_EOD)
434 {
435 StringView pathView = CreateStringViewFromString(path);
436 TraverseDottedPathAndAddLeafFieldNode(&pathView,
437 element,
438 root,
439 BsonDefaultCreateLeafNode,
440 treatLeafDataAsConstant,
441 &parseContext);
442 }
443
444 /* Create the node for the new indexField name */
445 if (indexFieldName != NULL)
446 {
447 bson_value_t indexValue;
448 memset(&indexValue, 0, sizeof(bson_value_t));
449 if (index > -1)
450 {
451 indexValue.value_type = BSON_TYPE_INT64;
452 indexValue.value.v_int64 = index;
453 }
454 else

Callers 1

BsonUnwindArrayFunction · 0.85

Calls 7

MakeRootNodeFunction · 0.85
PgbsonWriterInitFunction · 0.85
PgbsonInitIteratorFunction · 0.85
PgbsonWriterGetPgbsonFunction · 0.85

Tested by

no test coverage detected