예제 #1
0
    UpdateResult UpdateExecutor::execute(Database* db) {
        uassertStatusOK(prepare());

        LOG(3) << "processing update : " << *_request;

        // If we've already done the in-lock preparation, this is a no-op.
        Status status = prepareInLock(db);
        uassert(17243,
                "could not get executor " + _request->getQuery().toString()
                                         + "; " + causedBy(status),
                status.isOK());

        // Run the plan (don't need to collect results because UpdateStage always returns
        // NEED_TIME).
        uassertStatusOK(_exec->executePlan());

        // Get stats from the root stage.
        invariant(_exec->getRootStage()->stageType() == STAGE_UPDATE);
        UpdateStage* updateStage = static_cast<UpdateStage*>(_exec->getRootStage());
        const UpdateStats* updateStats =
            static_cast<const UpdateStats*>(updateStage->getSpecificStats());

        // Use stats from the root stage to fill out opDebug.
        _opDebug->nMatched = updateStats->nMatched;
        _opDebug->nModified = updateStats->nModified;
        _opDebug->upsert = updateStats->inserted;
        _opDebug->fastmodinsert = updateStats->fastmodinsert;
        _opDebug->fastmod = updateStats->fastmod;

        // Historically, 'opDebug' considers 'nMatched' and 'nModified' to be 1 (rather than 0) if
        // there is an upsert that inserts a document. The UpdateStage does not participate in this
        // madness in order to have saner stats reporting for explain. This means that we have to
        // set these values "manually" in the case of an insert.
        if (updateStats->inserted) {
            _opDebug->nMatched = 1;
            _opDebug->nModified = 1;
        }

        // Get summary information about the plan.
        PlanSummaryStats stats;
        Explain::getSummaryStats(_exec.get(), &stats);
        _opDebug->nscanned = stats.totalKeysExamined;
        _opDebug->nscannedObjects = stats.totalDocsExamined;

        return UpdateResult(updateStats->nMatched > 0 /* Did we update at least one obj? */,
                            !_driver.isDocReplacement() /* $mod or obj replacement */,
                            _opDebug->nModified /* number of modified docs, no no-ops */,
                            _opDebug->nMatched /* # of docs matched/updated, even no-ops */,
                            updateStats->objInserted);
    }
예제 #2
0
파일: update.cpp 프로젝트: zhihuiFan/mongo
const UpdateStats* UpdateStage::getUpdateStats(const PlanExecutor* exec) {
    invariant(exec->getRootStage()->isEOF());
    invariant(exec->getRootStage()->stageType() == STAGE_UPDATE);
    UpdateStage* updateStage = static_cast<UpdateStage*>(exec->getRootStage());
    return static_cast<const UpdateStats*>(updateStage->getSpecificStats());
}