Status ChunkManagerTargeter::targetDelete( const BatchedDeleteDocument& deleteDoc, vector<ShardEndpoint*>* endpoints ) const { Status result = targetQuery( deleteDoc.getQuery(), endpoints ); if ( !result.isOK() ) return result; if ( _manager ) { // // Sharded collections have the following further requirements for targeting: // // Limit-1 deletes must be targeted exactly by shard key *or* exact _id // bool exactShardKeyQuery = _manager->hasShardKey( deleteDoc.getQuery() ); bool exactIdQuery = isExactIdQuery( deleteDoc.getQuery() ); if ( deleteDoc.getLimit() == 1 && !exactShardKeyQuery && !exactIdQuery ) { return Status( ErrorCodes::ShardKeyNotFound, stream() << "delete " << deleteDoc.toBSON() << " does not contain _id or shard key for pattern " << _manager->getShardKey().key() ); } } return result; }
Status ChunkManagerTargeter::targetDelete(OperationContext* txn, const BatchedDeleteDocument& deleteDoc, vector<ShardEndpoint*>* endpoints) const { BSONObj shardKey; if (_manager) { // // Sharded collections have the following further requirements for targeting: // // Limit-1 deletes must be targeted exactly by shard key *or* exact _id // // Get the shard key StatusWith<BSONObj> status = _manager->getShardKeyPattern().extractShardKeyFromQuery(deleteDoc.getQuery()); // Bad query if (!status.isOK()) return status.getStatus(); shardKey = status.getValue(); // Validate that single (limit-1) sharded deletes are targeted by shard key or _id if (deleteDoc.getLimit() == 1 && shardKey.isEmpty() && !isExactIdQuery(deleteDoc.getQuery())) { return Status(ErrorCodes::ShardKeyNotFound, stream() << "delete " << deleteDoc.toBSON() << " does not contain _id or shard key for pattern " << _manager->getShardKeyPattern().toString()); } } // Target the shard key or delete query if (!shardKey.isEmpty()) { // We can't rely on our query targeting to be exact ShardEndpoint* endpoint = NULL; Status result = targetShardKey(txn, shardKey, 0, &endpoint); endpoints->push_back(endpoint); return result; } else { return targetQuery(deleteDoc.getQuery(), endpoints); } }
Status ChunkManagerTargeter::targetDelete( const BatchedDeleteDocument& deleteDoc, vector<ShardEndpoint*>* endpoints ) const { bool exactShardKeyQuery = false; if ( _manager ) { // // Sharded collections have the following further requirements for targeting: // // Limit-1 deletes must be targeted exactly by shard key *or* exact _id // exactShardKeyQuery = _manager->hasTargetableShardKey(deleteDoc.getQuery()); bool exactIdQuery = isExactIdQuery( deleteDoc.getQuery() ); if ( deleteDoc.getLimit() == 1 && !exactShardKeyQuery && !exactIdQuery ) { return Status( ErrorCodes::ShardKeyNotFound, stream() << "delete " << deleteDoc.toBSON() << " does not contain _id or shard key for pattern " << _manager->getShardKey().key() ); } } Status result = Status::OK(); if (exactShardKeyQuery) { // We can't rely on our query targeting to be exact ShardEndpoint* endpoint = NULL; result = targetShardKey(deleteDoc.getQuery(), &endpoint); endpoints->push_back(endpoint); invariant(result.isOK()); invariant(NULL != endpoint); } else { result = targetQuery(deleteDoc.getQuery(), endpoints); } return result; }
bool WriteBatchExecutor::doDelete( const string& ns, const BatchedDeleteDocument& deleteOp, CurOp* currentOp, WriteStats* stats, BatchedErrorDetail* error ) { OpDebug& opDebug = currentOp->debug(); _opCounters->gotDelete(); BSONObj queryObj = deleteOp.getQuery(); currentOp->setQuery( queryObj ); opDebug.op = dbDelete; opDebug.query = queryObj; long long n; try { n = deleteObjects( ns, queryObj, // ns, query deleteOp.getLimit() == 1, // justOne true, // logOp false // god ); stats->numDeleted += n; } catch ( const UserException& ex ) { opDebug.exceptionInfo = ex.getInfo(); toBatchedError( ex, error ); return false; } _le->recordDelete( n ); opDebug.ndeleted = n; return true; }