// static void ProjectionStage::getSimpleInclusionFields(const BSONObj& projObj, FieldSet* includedFields) { // The _id is included by default. bool includeId = true; // Figure out what fields are in the projection. TODO: we can get this from the // ParsedProjection...modify that to have this type instead of a vector. BSONObjIterator projObjIt(projObj); while (projObjIt.more()) { BSONElement elt = projObjIt.next(); // Must deal with the _id case separately as there is an implicit _id: 1 in the // projection. if (mongoutils::str::equals(elt.fieldName(), kIdField) && !elt.trueValue()) { includeId = false; continue; } includedFields->insert(elt.fieldNameStringData()); } if (includeId) { includedFields->insert(kIdField); } }
ProjectionStage::ProjectionStage(const ProjectionStageParams& params, WorkingSet* ws, PlanStage* child) : _ws(ws), _child(child), _projImpl(params.projImpl) { if (ProjectionStageParams::NO_FAST_PATH == _projImpl) { _exec.reset(new ProjectionExec(params.projObj, params.fullExpression)); } else { // We shouldn't need the full expression if we're fast-pathing. invariant(NULL == params.fullExpression); _projObj = params.projObj; // Sanity-check the input. invariant(_projObj.isOwned()); invariant(!_projObj.isEmpty()); // The _id is included by default. bool includeId = true; // Figure out what fields are in the projection. TODO: we can get this from the // ParsedProjection...modify that to have this type instead of a vector. BSONObjIterator projObjIt(_projObj); while (projObjIt.more()) { BSONElement elt = projObjIt.next(); // Must deal with the _id case separately as there is an implicit _id: 1 in the // projection. if (mongoutils::str::equals(elt.fieldName(), kIdField) && !elt.trueValue()) { includeId = false; continue; } _includedFields.insert(elt.fieldNameStringData()); } if (includeId) { _includedFields.insert(kIdField); } // If we're pulling data out of one index we can pre-compute the indices of the fields // in the key that we pull data from and avoid looking up the field name each time. if (ProjectionStageParams::COVERED_ONE_INDEX == params.projImpl) { // Sanity-check. _coveredKeyObj = params.coveredKeyObj; invariant(_coveredKeyObj.isOwned()); BSONObjIterator kpIt(_coveredKeyObj); while (kpIt.more()) { BSONElement elt = kpIt.next(); unordered_set<StringData, StringData::Hasher>::iterator fieldIt; fieldIt = _includedFields.find(elt.fieldNameStringData()); if (_includedFields.end() == fieldIt) { // Push an unused value on the back to keep _includeKey and _keyFieldNames // in sync. _keyFieldNames.push_back(StringData()); _includeKey.push_back(false); } else { // If we are including this key field store its field name. _keyFieldNames.push_back(*fieldIt); _includeKey.push_back(true); } } } else { invariant(ProjectionStageParams::SIMPLE_DOC == params.projImpl); } } }