boost::optional<Document> DocumentSourceRedact::redactObject() { const Value expressionResult = _expression->evaluate(_variables.get()); if (expressionResult == keepVal) { return _variables->getDocument(_currentId); } else if (expressionResult == pruneVal) { return boost::optional<Document>(); } else if (expressionResult == descendVal) { const Document in = _variables->getDocument(_currentId); MutableDocument out; out.copyMetaDataFrom(in); FieldIterator fields(in); while (fields.more()) { const Document::FieldPair field(fields.next()); // This changes CURRENT so don't read from _variables after this const Value val = redactValue(field.second); if (!val.missing()) { out.addField(field.first, val); } } return out.freeze(); } else { uasserted(17053, str::stream() << "$redact's expression should not return anything " << "aside from the variables $$KEEP, $$DESCEND, and " << "$$PRUNE, but returned " << expressionResult.toString()); } }
boost::optional<Document> DocumentSourceProject::getNext() { pExpCtx->checkForInterrupt(); boost::optional<Document> input = pSource->getNext(); if (!input) return boost::none; /* create the result document */ const size_t sizeHint = pEO->getSizeHint(); MutableDocument out (sizeHint); out.copyMetaDataFrom(*input); /* Use the ExpressionObject to create the base result. If we're excluding fields at the top level, leave out the _id if it is found, because we took care of it above. */ _variables->setRoot(*input); pEO->addToDocument(out, *input, _variables.get()); _variables->clearRoot(); #if defined(_DEBUG) if (!_simpleProjection.getSpec().isEmpty()) { // Make sure we return the same results as Projection class BSONObj inputBson = input->toBson(); BSONObj outputBson = out.peek().toBson(); BSONObj projected = _simpleProjection.transform(inputBson); if (projected != outputBson) { log() << "$project applied incorrectly: " << getRaw() << endl; log() << "input: " << inputBson << endl; log() << "out: " << outputBson << endl; log() << "projected: " << projected << endl; verify(false); // exits in _DEBUG builds } } #endif return out.freeze(); }
boost::optional<Document> DocumentSourceProject::getNext() { pExpCtx->checkForInterrupt(); boost::optional<Document> input = pSource->getNext(); if (!input) return boost::none; /* create the result document */ const size_t sizeHint = pEO->getSizeHint(); MutableDocument out (sizeHint); out.copyMetaDataFrom(*input); /* Use the ExpressionObject to create the base result. If we're excluding fields at the top level, leave out the _id if it is found, because we took care of it above. */ _variables->setRoot(*input); pEO->addToDocument(out, *input, _variables.get()); _variables->clearRoot(); return out.freeze(); }