bool errmsgRun(OperationContext* opCtx, const string& dbname, const BSONObj& cmdObj, string& errmsg, BSONObjBuilder& result) { const NamespaceString nss = CommandHelpers::parseNsCollectionRequired(dbname, cmdObj); AutoGetCollectionForReadCommand ctx(opCtx, nss); // Check whether we are allowed to read from this node after acquiring our locks. auto replCoord = repl::ReplicationCoordinator::get(opCtx); uassertStatusOK(replCoord->checkCanServeReadsFor( opCtx, nss, ReadPreferenceSetting::get(opCtx).canRunOnSecondary())); Collection* collection = ctx.getCollection(); if (!collection) { errmsg = "can't find ns"; return false; } vector<IndexDescriptor*> idxs; collection->getIndexCatalog()->findIndexByType(opCtx, IndexNames::GEO_HAYSTACK, idxs); if (idxs.size() == 0) { errmsg = "no geoSearch index"; return false; } if (idxs.size() > 1) { errmsg = "more than 1 geosearch index"; return false; } BSONElement nearElt = cmdObj["near"]; BSONElement maxDistance = cmdObj["maxDistance"]; BSONElement search = cmdObj["search"]; uassert(13318, "near needs to be an array", nearElt.isABSONObj()); uassert(13319, "maxDistance needs a number", maxDistance.isNumber()); uassert(13320, "search needs to be an object", search.type() == Object); unsigned limit = 50; if (cmdObj["limit"].isNumber()) limit = static_cast<unsigned>(cmdObj["limit"].numberInt()); IndexDescriptor* desc = idxs[0]; HaystackAccessMethod* ham = static_cast<HaystackAccessMethod*>(collection->getIndexCatalog()->getIndex(desc)); ham->searchCommand(opCtx, collection, nearElt.Obj(), maxDistance.numberDouble(), search.Obj(), &result, limit); return 1; }
bool run(OperationContext* txn, const string& dbname, BSONObj& cmdObj, int, string& errmsg, BSONObjBuilder& result) { const std::string ns = parseNsCollectionRequired(dbname, cmdObj); AutoGetCollectionForRead ctx(txn, ns); Collection* collection = ctx.getCollection(); if (!collection) { errmsg = "can't find ns"; return false; } vector<IndexDescriptor*> idxs; collection->getIndexCatalog()->findIndexByType(txn, IndexNames::GEO_HAYSTACK, idxs); if (idxs.size() == 0) { errmsg = "no geoSearch index"; return false; } if (idxs.size() > 1) { errmsg = "more than 1 geosearch index"; return false; } BSONElement nearElt = cmdObj["near"]; BSONElement maxDistance = cmdObj["maxDistance"]; BSONElement search = cmdObj["search"]; uassert(13318, "near needs to be an array", nearElt.isABSONObj()); uassert(13319, "maxDistance needs a number", maxDistance.isNumber()); uassert(13320, "search needs to be an object", search.type() == Object); unsigned limit = 50; if (cmdObj["limit"].isNumber()) limit = static_cast<unsigned>(cmdObj["limit"].numberInt()); IndexDescriptor* desc = idxs[0]; HaystackAccessMethod* ham = static_cast<HaystackAccessMethod*>(collection->getIndexCatalog()->getIndex(desc)); ham->searchCommand(txn, collection, nearElt.Obj(), maxDistance.numberDouble(), search.Obj(), &result, limit); return 1; }
bool run(OperationContext* txn, const string& dbname, BSONObj& cmdObj, int, string& errmsg, BSONObjBuilder& result, bool fromRepl) { const string ns = dbname + "." + cmdObj.firstElement().valuestr(); Client::ReadContext ctx(ns); Database* db = ctx.ctx().db(); if ( !db ) { errmsg = "can't find ns"; return false; } Collection* collection = db->getCollection( ns ); if ( !collection ) { errmsg = "can't find ns"; return false; } vector<IndexDescriptor*> idxs; collection->getIndexCatalog()->findIndexByType(IndexNames::GEO_HAYSTACK, idxs); if (idxs.size() == 0) { errmsg = "no geoSearch index"; return false; } if (idxs.size() > 1) { errmsg = "more than 1 geosearch index"; return false; } BSONElement nearElt = cmdObj["near"]; BSONElement maxDistance = cmdObj["maxDistance"]; BSONElement search = cmdObj["search"]; uassert(13318, "near needs to be an array", nearElt.isABSONObj()); uassert(13319, "maxDistance needs a number", maxDistance.isNumber()); uassert(13320, "search needs to be an object", search.type() == Object); unsigned limit = 50; if (cmdObj["limit"].isNumber()) limit = static_cast<unsigned>(cmdObj["limit"].numberInt()); IndexDescriptor* desc = idxs[0]; HaystackAccessMethod* ham = static_cast<HaystackAccessMethod*>( collection->getIndexCatalog()->getIndex(desc) ); ham->searchCommand(nearElt.Obj(), maxDistance.numberDouble(), search.Obj(), &result, limit); return 1; }