// Find the keys for obj, put them in the tree pointing to loc Status BtreeBasedAccessMethod::insert(OperationContext* txn, const BSONObj& obj, const DiskLoc& loc, const InsertDeleteOptions& options, int64_t* numInserted) { *numInserted = 0; BSONObjSet keys; // Delegate to the subclass. getKeys(obj, &keys); Status ret = Status::OK(); for (BSONObjSet::const_iterator i = keys.begin(); i != keys.end(); ++i) { Status status = _newInterface->insert(txn, *i, loc, options.dupsAllowed); // Everything's OK, carry on. if (status.isOK()) { ++*numInserted; continue; } // Error cases. if (ErrorCodes::KeyTooLong == status.code()) { // Ignore this error if we're on a secondary. if (!txn->isPrimaryFor(_btreeState->ns())) { continue; } // The user set a parameter to ignore key too long errors. if (!failIndexKeyTooLong) { continue; } } if (ErrorCodes::UniqueIndexViolation == status.code()) { // We ignore it for some reason in BG indexing. if (!_btreeState->isReady()) { DEV log() << "info: key already in index during bg indexing (ok)\n"; continue; } } // Clean up after ourselves. for (BSONObjSet::const_iterator j = keys.begin(); j != i; ++j) { removeOneKey(txn, *j, loc); *numInserted = 0; } return status; } if (*numInserted > 1) { _btreeState->setMultikey( txn ); } return ret; }
Status AbstractIndexAccessMethod::removeKeys(OperationContext* opCtx, const BSONObjSet& keys, const RecordId& loc, const InsertDeleteOptions& options, int64_t* numDeleted) { for (const auto& key : keys) { removeOneKey(opCtx, key, loc, options.dupsAllowed); } *numDeleted = keys.size(); return Status::OK(); }
// Remove the provided doc from the index. Status IndexAccessMethod::remove(OperationContext* txn, const BSONObj& obj, const RecordId& loc, const InsertDeleteOptions& options, int64_t* numDeleted) { BSONObjSet keys; getKeys(obj, &keys); *numDeleted = 0; for (BSONObjSet::const_iterator i = keys.begin(); i != keys.end(); ++i) { removeOneKey(txn, *i, loc, options.dupsAllowed); ++*numDeleted; } return Status::OK(); }
// Find the keys for obj, put them in the tree pointing to loc Status BtreeBasedAccessMethod::insert(const BSONObj& obj, const DiskLoc& loc, const InsertDeleteOptions& options, int64_t* numInserted) { *numInserted = 0; BSONObjSet keys; // Delegate to the subclass. getKeys(obj, &keys); Status ret = Status::OK(); for (BSONObjSet::const_iterator i = keys.begin(); i != keys.end(); ++i) { try { _interface->bt_insert(_btreeState, _btreeState->head(), loc, *i, options.dupsAllowed, true); ++*numInserted; } catch (AssertionException& e) { if (10287 == e.getCode() && !_btreeState->isReady()) { // This is the duplicate key exception. We ignore it for some reason in BG // indexing. DEV log() << "info: key already in index during bg indexing (ok)\n"; } else if (!options.dupsAllowed) { // Assuming it's a duplicate key exception. Clean up any inserted keys. for (BSONObjSet::const_iterator j = keys.begin(); j != i; ++j) { removeOneKey(*j, loc); } *numInserted = 0; return Status(ErrorCodes::DuplicateKey, e.what(), e.getCode()); } else { problem() << " caught assertion addKeysToIndex " << _descriptor->indexNamespace() << obj["_id"] << endl; ret = Status(ErrorCodes::InternalError, e.what(), e.getCode()); } } } if (*numInserted > 1) { _btreeState->setMultikey(); } return ret; }
// Remove the provided doc from the index. Status BtreeBasedAccessMethod::remove(const BSONObj &obj, const DiskLoc& loc, const InsertDeleteOptions &options, int64_t* numDeleted) { BSONObjSet keys; getKeys(obj, &keys); *numDeleted = 0; for (BSONObjSet::const_iterator i = keys.begin(); i != keys.end(); ++i) { bool thisKeyOK = removeOneKey(*i, loc); if (thisKeyOK) { ++*numDeleted; } else if (options.logIfError) { log() << "unindex failed (key too big?) " << _descriptor->indexNamespace() << " key: " << *i << " " << loc.obj()["_id"] << endl; } } return Status::OK(); }
// Remove the provided doc from the index. Status IndexAccessMethod::remove(OperationContext* txn, const BSONObj& obj, const RecordId& loc, const InsertDeleteOptions& options, int64_t* numDeleted) { invariant(numDeleted); *numDeleted = 0; BSONObjSet keys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); // There's no need to compute the prefixes of the indexed fields that cause the index to be // multikey when removing a document since the index metadata isn't updated when keys are // deleted. MultikeyPaths* multikeyPaths = nullptr; getKeys(obj, &keys, multikeyPaths); for (BSONObjSet::const_iterator i = keys.begin(); i != keys.end(); ++i) { removeOneKey(txn, *i, loc, options.dupsAllowed); ++*numDeleted; } return Status::OK(); }
// Remove the provided doc from the index. Status IndexAccessMethod::remove(OperationContext* opCtx, const BSONObj& obj, const RecordId& loc, const InsertDeleteOptions& options, int64_t* numDeleted) { invariant(numDeleted); *numDeleted = 0; BSONObjSet keys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); // There's no need to compute the prefixes of the indexed fields that cause the index to be // multikey when removing a document since the index metadata isn't updated when keys are // deleted. MultikeyPaths* multikeyPaths = nullptr; // Relax key constraints on removal when deleting documents with invalid formats, but only // those that don't apply to the partialIndex filter. getKeys(obj, GetKeysMode::kRelaxConstraintsUnfiltered, &keys, multikeyPaths); for (BSONObjSet::const_iterator i = keys.begin(); i != keys.end(); ++i) { removeOneKey(opCtx, *i, loc, options.dupsAllowed); ++*numDeleted; } return Status::OK(); }