/** * Looks in the children stored in the 'nodes' field of 'testSoln' * to see if thet match the 'children' field of 'trueSoln'. * * This does an unordered comparison, i.e. childrenMatch returns * true as long as the set of subtrees in testSoln's 'nodes' matches * the set of subtrees in trueSoln's 'children' vector. */ static bool childrenMatch(const BSONObj& testSoln, const QuerySolutionNode* trueSoln) { BSONElement children = testSoln["nodes"]; if (children.eoo() || !children.isABSONObj()) { return false; } // The order of the children array in testSoln might not match // the order in trueSoln, so we have to check all combos with // these nested loops. BSONObjIterator i(children.Obj()); while (i.more()) { BSONElement child = i.next(); if (child.eoo() || !child.isABSONObj()) { return false; } // try to match against one of the QuerySolutionNode's children bool found = false; for (size_t j = 0; j < trueSoln->children.size(); ++j) { if (QueryPlannerTestLib::solutionMatches(child.Obj(), trueSoln->children[j])) { found = true; break; } } // we couldn't match child if (!found) { return false; } } return true; }
// This function starts a program. In its input array it accepts either all commandline tokens // which will be executed, or a single Object which must have a field named "args" which contains // an array with all commandline tokens. The Object may have a field named "env" which contains an // object of Key Value pairs which will be loaded into the environment of the spawned process. BSONObj StartMongoProgram(const BSONObj& a, void* data) { _nokillop = true; BSONObj args = a; BSONObj env{}; BSONElement firstElement = args.firstElement(); if (firstElement.ok() && firstElement.isABSONObj()) { BSONObj subobj = firstElement.Obj(); BSONElement argsElem = subobj["args"]; BSONElement envElem = subobj["env"]; uassert(40098, "If StartMongoProgram is called with a BSONObj, " "it must contain an 'args' subobject." + args.toString(), argsElem.ok() && argsElem.isABSONObj()); args = argsElem.Obj(); if (envElem.ok() && envElem.isABSONObj()) { env = envElem.Obj(); } } ProgramRunner r(args, env); r.start(); invariant(registry.isPidRegistered(r.pid())); stdx::thread t(r); registry.registerReaderThread(r.pid(), std::move(t)); return BSON(string("") << r.pid().asLongLong()); }
void ParsedQuery::init( const BSONObj& q ) { _reset(); uassert( 10105 , "bad skip value in query", _ntoskip >= 0); if ( _ntoreturn < 0 ) { /* _ntoreturn greater than zero is simply a hint on how many objects to send back per "cursor batch". A negative number indicates a hard limit. */ _wantMore = false; _ntoreturn = -_ntoreturn; } BSONElement e = q["query"]; if ( ! e.isABSONObj() ) e = q["$query"]; if ( e.isABSONObj() ) { _filter = e.embeddedObject().getOwned(); _initTop( q ); } else { _filter = q.getOwned(); } _hasReadPref = q.hasField(Query::ReadPrefField.name()); }
/* * Recurses over all fields in the obj to match against phrase * @param phrase, string to be matched * @param obj, object to matched against */ bool FTSMatcher::_phraseRecurse( const string& phrase, const BSONObj& obj ) const { BSONObjIterator j( obj ); while ( j.more() ) { BSONElement x = j.next(); if ( _spec.languageOverrideField() == x.fieldName() ) continue; if ( x.type() == String ) { if ( _phraseMatches( phrase, x.String() ) ) return true; } else if ( x.isABSONObj() ) { BSONObjIterator k( x.Obj() ); while ( k.more() ) { BSONElement y = k.next(); if ( y.type() == mongo::String ) { if ( _phraseMatches( phrase, y.String() ) ) return true; } else if ( y.isABSONObj() ) { if ( _phraseRecurse( phrase, y.Obj() ) ) return true; } } } } return false; }
bool FTSMatcher::_hasNegativeTerm_recurse(const BSONObj& obj ) const { BSONObjIterator j( obj ); while ( j.more() ) { BSONElement x = j.next(); if ( _spec.languageOverrideField() == x.fieldName()) continue; if (x.type() == String) { if ( _hasNegativeTerm_string( x.String() ) ) return true; } else if ( x.isABSONObj() ) { BSONObjIterator k( x.Obj() ); while ( k.more() ) { // check if k.next() is a obj/array or not BSONElement y = k.next(); if ( y.type() == String ) { if ( _hasNegativeTerm_string( y.String() ) ) return true; } else if ( y.isABSONObj() ) { if ( _hasNegativeTerm_recurse( y.Obj() ) ) return true; } } } } return false; }
bool run(OperationContext* txn, const string& dbname, BSONObj& cmdObj, int, string& errmsg, BSONObjBuilder& result, bool fromRepl) { BSONElement argElt = cmdObj["stageDebug"]; if (argElt.eoo() || !argElt.isABSONObj()) { return false; } BSONObj argObj = argElt.Obj(); // Pull out the collection name. BSONElement collElt = argObj["collection"]; if (collElt.eoo() || (String != collElt.type())) { return false; } string collName = collElt.String(); // Need a context to get the actual Collection* // TODO A write lock is currently taken here to accommodate stages that perform writes // (e.g. DeleteStage). This should be changed to use a read lock for read-only // execution trees. ScopedTransaction transaction(txn, MODE_IX); Lock::DBLock lk(txn->lockState(), dbname, MODE_X); Client::Context ctx(txn, dbname); // Make sure the collection is valid. Database* db = ctx.db(); Collection* collection = db->getCollection(db->name() + '.' + collName); uassert(17446, "Couldn't find the collection " + collName, NULL != collection); // Pull out the plan BSONElement planElt = argObj["plan"]; if (planElt.eoo() || !planElt.isABSONObj()) { return false; } BSONObj planObj = planElt.Obj(); // Parse the plan into these. OwnedPointerVector<MatchExpression> exprs; auto_ptr<WorkingSet> ws(new WorkingSet()); PlanStage* userRoot = parseQuery(txn, collection, planObj, ws.get(), &exprs); uassert(16911, "Couldn't parse plan from " + cmdObj.toString(), NULL != userRoot); // Add a fetch at the top for the user so we can get obj back for sure. // TODO: Do we want to do this for the user? I think so. PlanStage* rootFetch = new FetchStage(txn, ws.get(), userRoot, NULL, collection); PlanExecutor* rawExec; Status execStatus = PlanExecutor::make(txn, ws.release(), rootFetch, collection, PlanExecutor::YIELD_MANUAL, &rawExec); fassert(28536, execStatus); boost::scoped_ptr<PlanExecutor> exec(rawExec); BSONArrayBuilder resultBuilder(result.subarrayStart("results")); for (BSONObj obj; PlanExecutor::ADVANCED == exec->getNext(&obj, NULL); ) { resultBuilder.append(obj); } resultBuilder.done(); return true; }
bool GeoQuery::parseNewQuery(const BSONObj &obj) { // pointA = { "type" : "Point", "coordinates": [ 40, 5 ] } // t.find({ "geo" : { "$intersect" : { "$geometry" : pointA} } }) // t.find({ "geo" : { "$within" : { "$geometry" : polygon } } }) // where field.name is "geo" BSONElement e = obj.firstElement(); if (!e.isABSONObj()) { return false; } BSONObj::MatchType matchType = static_cast<BSONObj::MatchType>(e.getGtLtOp()); if (BSONObj::opGEO_INTERSECTS == matchType) { predicate = GeoQuery::INTERSECT; } else if (BSONObj::opWITHIN == matchType) { predicate = GeoQuery::WITHIN; } else { return false; } bool hasGeometry = false; BSONObjIterator argIt(e.embeddedObject()); while (argIt.more()) { BSONElement e = argIt.next(); if (mongoutils::str::equals(e.fieldName(), "$geometry")) { if (e.isABSONObj()) { BSONObj embeddedObj = e.embeddedObject(); if (geoContainer.parseFrom(embeddedObj)) { hasGeometry = true; } } } } // Don't want to give the error below if we could not pull any geometry out. if (!hasGeometry) { return false; } if (GeoQuery::WITHIN == predicate) { // Why do we only deal with $within {polygon}? // 1. Finding things within a point is silly and only valid // for points and degenerate lines/polys. // // 2. Finding points within a line is easy but that's called intersect. // Finding lines within a line is kind of tricky given what S2 gives us. // Doing line-within-line is a valid yet unsupported feature, // though I wonder if we want to preserve orientation for lines or // allow (a,b),(c,d) to be within (c,d),(a,b). Anyway, punt on // this for now. uassert(16672, "$within not supported with provided geometry: " + obj.toString(), geoContainer.supportsContains()); } return hasGeometry; }
bool GeoParser::isLegacyBox(const BSONObj &obj) { BSONObjIterator coordIt(obj); BSONElement minE = coordIt.next(); if (!minE.isABSONObj()) { return false; } if (!isLegacyPoint(minE.Obj())) { return false; } if (!coordIt.more()) { return false; } BSONElement maxE = coordIt.next(); if (!maxE.isABSONObj()) { return false; } if (!isLegacyPoint(maxE.Obj())) { return false; } return true; }
void ParsedQuery::init( const BSONObj& q ) { _reset(); uassert( 10105 , "bad skip value in query", _ntoskip >= 0); if ( _ntoreturn < 0 ) { /* _ntoreturn greater than zero is simply a hint on how many objects to send back per "cursor batch". A negative number indicates a hard limit. */ _wantMore = false; _ntoreturn = -_ntoreturn; } BSONElement e = q["query"]; if ( ! e.isABSONObj() ) e = q["$query"]; if ( e.isABSONObj() ) { _filter = e.embeddedObject(); _initTop( q ); } else { _filter = q; } _filter = _filter.getOwned(); // // Parse options that are valid for both queries and commands // // $readPreference _hasReadPref = q.hasField(Query::ReadPrefField.name()); // $maxTimeMS BSONElement maxTimeMSElt = q.getField("$maxTimeMS"); if (!maxTimeMSElt.eoo()) { uassert(16987, mongoutils::str::stream() << "$maxTimeMS must be a number type, instead found type: " << maxTimeMSElt.type(), maxTimeMSElt.isNumber()); } // If $maxTimeMS was not specified, _maxTimeMS is set to 0 (special value for "allow to // run indefinitely"). long long maxTimeMSLongLong = maxTimeMSElt.safeNumberLong(); uassert(16988, "$maxTimeMS out of range [0,2147483647]", maxTimeMSLongLong >= 0 && maxTimeMSLongLong <= INT_MAX); _maxTimeMS = static_cast<int>(maxTimeMSLongLong); }
// static Status PlanCacheCommand::canonicalize(OperationContext* txn, const string& ns, const BSONObj& cmdObj, CanonicalQuery** canonicalQueryOut) { // query - required BSONElement queryElt = cmdObj.getField("query"); if (queryElt.eoo()) { return Status(ErrorCodes::BadValue, "required field query missing"); } if (!queryElt.isABSONObj()) { return Status(ErrorCodes::BadValue, "required field query must be an object"); } if (queryElt.eoo()) { return Status(ErrorCodes::BadValue, "required field query missing"); } BSONObj queryObj = queryElt.Obj(); // sort - optional BSONElement sortElt = cmdObj.getField("sort"); BSONObj sortObj; if (!sortElt.eoo()) { if (!sortElt.isABSONObj()) { return Status(ErrorCodes::BadValue, "optional field sort must be an object"); } sortObj = sortElt.Obj(); } // projection - optional BSONElement projElt = cmdObj.getField("projection"); BSONObj projObj; if (!projElt.eoo()) { if (!projElt.isABSONObj()) { return Status(ErrorCodes::BadValue, "optional field projection must be an object"); } projObj = projElt.Obj(); } // Create canonical query CanonicalQuery* cqRaw; const NamespaceString nss(ns); const WhereCallbackReal whereCallback(txn, nss.db()); Status result = CanonicalQuery::canonicalize( ns, queryObj, sortObj, projObj, &cqRaw, whereCallback); if (!result.isOK()) { return result; } *canonicalQueryOut = cqRaw; return Status::OK(); }
// static StatusWith<unique_ptr<CanonicalQuery>> PlanCacheCommand::canonicalize(OperationContext* txn, const string& ns, const BSONObj& cmdObj) { // query - required BSONElement queryElt = cmdObj.getField("query"); if (queryElt.eoo()) { return Status(ErrorCodes::BadValue, "required field query missing"); } if (!queryElt.isABSONObj()) { return Status(ErrorCodes::BadValue, "required field query must be an object"); } if (queryElt.eoo()) { return Status(ErrorCodes::BadValue, "required field query missing"); } BSONObj queryObj = queryElt.Obj(); // sort - optional BSONElement sortElt = cmdObj.getField("sort"); BSONObj sortObj; if (!sortElt.eoo()) { if (!sortElt.isABSONObj()) { return Status(ErrorCodes::BadValue, "optional field sort must be an object"); } sortObj = sortElt.Obj(); } // projection - optional BSONElement projElt = cmdObj.getField("projection"); BSONObj projObj; if (!projElt.eoo()) { if (!projElt.isABSONObj()) { return Status(ErrorCodes::BadValue, "optional field projection must be an object"); } projObj = projElt.Obj(); } // Create canonical query const NamespaceString nss(ns); auto qr = stdx::make_unique<QueryRequest>(std::move(nss)); qr->setFilter(queryObj); qr->setSort(sortObj); qr->setProj(projObj); const ExtensionsCallbackReal extensionsCallback(txn, &nss); auto statusWithCQ = CanonicalQuery::canonicalize(txn, std::move(qr), extensionsCallback); if (!statusWithCQ.isOK()) { return statusWithCQ.getStatus(); } return std::move(statusWithCQ.getValue()); }
static bool isLegacyCenter(const BSONObj &obj) { BSONObjIterator typeIt(obj); BSONElement type = typeIt.next(); if (!type.isABSONObj()) { return false; } bool isCenter = mongoutils::str::equals(type.fieldName(), "$center"); if (!isCenter) { return false; } BSONObjIterator objIt(type.embeddedObject()); BSONElement center = objIt.next(); if (!center.isABSONObj()) { return false; } if (!isLegacyPoint(center.Obj())) { return false; } if (!objIt.more()) { return false; } BSONElement radius = objIt.next(); if (!radius.isNumber()) { return false; } return true; }
bool GeoParser::isLegacyBox(const BSONObj &obj) { BSONObjIterator typeIt(obj); BSONElement type = typeIt.next(); if (!type.isABSONObj()) { return false; } if (!mongoutils::str::equals(type.fieldName(), "$box")) { return false; } BSONObjIterator coordIt(type.embeddedObject()); BSONElement minE = coordIt.next(); if (!minE.isABSONObj()) { return false; } if (!isLegacyPoint(minE.Obj())) { return false; } if (!coordIt.more()) { return false; } BSONElement maxE = coordIt.next(); if (!maxE.isABSONObj()) { return false; } if (!isLegacyPoint(maxE.Obj())) { return false; } return true; }
void BSONCollectionCatalogEntry::MetaData::parse(const BSONObj& obj) { ns = obj["ns"].valuestrsafe(); if (obj["options"].isABSONObj()) { options.parse(obj["options"].Obj(), CollectionOptions::parseForStorage) .transitional_ignore(); } BSONElement indexList = obj["indexes"]; if (indexList.isABSONObj()) { for (BSONElement elt : indexList.Obj()) { BSONObj idx = elt.Obj(); IndexMetaData imd; imd.spec = idx["spec"].Obj().getOwned(); imd.ready = idx["ready"].trueValue(); if (idx.hasField("head")) { imd.head = RecordId(idx["head"].Long()); } else { imd.head = RecordId(idx["head_a"].Int(), idx["head_b"].Int()); } imd.multikey = idx["multikey"].trueValue(); if (auto multikeyPathsElem = idx["multikeyPaths"]) { parseMultikeyPathsFromBytes(multikeyPathsElem.Obj(), &imd.multikeyPaths); } imd.prefix = KVPrefix::fromBSONElement(idx["prefix"]); indexes.push_back(imd); } } prefix = KVPrefix::fromBSONElement(obj["prefix"]); }
bool GeoMatchExpression::matchesSingleElement( const BSONElement& e ) const { if ( !e.isABSONObj()) return false; GeometryContainer geometry; if ( !geometry.parseFromStorage( e ).isOK() ) return false; // Never match big polygon if (geometry.getNativeCRS() == STRICT_SPHERE) return false; // Project this geometry into the CRS of the query if (!geometry.supportsProject(_query->getGeometry().getNativeCRS())) return false; geometry.projectInto(_query->getGeometry().getNativeCRS()); if (GeoExpression::WITHIN == _query->getPred()) { return _query->getGeometry().contains(geometry); } else { verify(GeoExpression::INTERSECT == _query->getPred()); return _query->getGeometry().intersects(geometry); } }
/** * Checks if phrase is exactly matched in obj, returns true if so, false otherwise * @param phrase, the string to be matched * @param obj, document in the collection to match against */ bool FTSMatcher::phraseMatch( const string& phrase, const BSONObj& obj ) const { if ( _spec.wildcard() ) { // case where everything is indexed (all fields) return _phraseRecurse( phrase, obj ); } for ( Weights::const_iterator i = _spec.weights().begin(); i != _spec.weights().end(); ++i ) { // figure out what the indexed field is.. ie. is it "field" or "field.subfield" etc. const char * leftOverName = i->first.c_str(); BSONElement e = obj.getFieldDottedOrArray(leftOverName); if ( e.type() == Array ) { BSONObjIterator j( e.Obj() ); while ( j.more() ) { BSONElement x = j.next(); if ( leftOverName[0] && x.isABSONObj() ) x = x.Obj().getFieldDotted( leftOverName ); if ( x.type() == String ) if ( _phraseMatches( phrase, x.String() ) ) return true; } } else if ( e.type() == String ) { if ( _phraseMatches( phrase, e.String() ) ) return true; } } return false; }
bool AllMatchExpression::matches( const BSONObj& doc, MatchDetails* details ) const { FieldRef path; path.parse(_path); bool traversedArray = false; int32_t idxPath = 0; BSONElement e = getFieldDottedOrArray( doc, path, &idxPath, &traversedArray ); string rest = pathToString( path, idxPath+1 ); if ( e.type() != Array || traversedArray || rest.size() == 0 ) { return matchesSingleElement( e ); } BSONElementSet all; BSONObjIterator i( e.Obj() ); while ( i.more() ) { BSONElement e = i.next(); if ( ! e.isABSONObj() ) continue; e.Obj().getFieldsDotted( rest, all ); } return _match( all ); }
std::vector<std::string> KVCatalog::getAllIdents(OperationContext* opCtx) const { std::vector<std::string> v; auto cursor = _rs->getCursor(opCtx); while (auto record = cursor->next()) { BSONObj obj = record->data.releaseToBson(); if (FeatureTracker::isFeatureDocument(obj)) { // Skip over the version document because it doesn't correspond to a namespace entry and // therefore doesn't refer to any idents. continue; } v.push_back(obj["ident"].String()); BSONElement e = obj["idxIdent"]; if (!e.isABSONObj()) continue; BSONObj idxIdent = e.Obj(); BSONObjIterator sub(idxIdent); while (sub.more()) { BSONElement e = sub.next(); v.push_back(e.String()); } } return v; }
void getKeys( const BSONObj &obj, BSONObjSet &keys ) const { BSONElement loc = obj.getFieldDotted( _geo ); if ( loc.eoo() ) return; uassert( 13323 , "latlng not an array" , loc.isABSONObj() ); string root; { BSONObjIterator i( loc.Obj() ); BSONElement x = i.next(); BSONElement y = i.next(); root = makeString( hash(x) , hash(y) ); } verify( _other.size() == 1 ); BSONElementSet all; obj.getFieldsDotted( _other[0] , all ); if ( all.size() == 0 ) { _add( obj , root , BSONElement() , keys ); } else { for ( BSONElementSet::iterator i=all.begin(); i!=all.end(); ++i ) { _add( obj , root , *i , keys ); } } }
Status FTSSpec::getIndexPrefix( const BSONObj& query, BSONObj* out ) const { if ( numExtraBefore() == 0 ) { *out = BSONObj(); return Status::OK(); } BSONObjBuilder b; for ( unsigned i = 0; i < numExtraBefore(); i++ ) { BSONElement e = query.getFieldDotted(extraBefore(i)); if ( e.eoo() ) return Status( ErrorCodes::BadValue, str::stream() << "need have an equality filter on: " << extraBefore(i) ); if ( e.isABSONObj() && e.Obj().firstElement().getGtLtOp( -1 ) != -1 ) return Status( ErrorCodes::BadValue, str::stream() << "need have an equality filter on: " << extraBefore(i) ); b.append( e ); } *out = b.obj(); return Status::OK(); }
NamespaceStats getDataTop() { NamespaceStats stats; BSONObj out; if ( ! conn().simpleCommand( _db , &out , "top" ) ) { cout << "error: " << out << endl; return stats; } if ( ! out["totals"].isABSONObj() ) { cout << "error: invalid top\n" << out << endl; return stats; } out = out["totals"].Obj().getOwned(); BSONObjIterator i( out ); while ( i.more() ) { BSONElement e = i.next(); if ( ! e.isABSONObj() ) continue; NamespaceInfo& s = stats[e.fieldName()]; s.ns = e.fieldName(); s.read = e.Obj()["readLock"].Obj()["time"].numberLong() / 1000; s.write = e.Obj()["writeLock"].Obj()["time"].numberLong() / 1000; } return stats; }
static bool isLegacyPolygon(const BSONObj &obj) { BSONObjIterator typeIt(obj); BSONElement type = typeIt.next(); if (!type.isABSONObj()) { return false; } if (!mongoutils::str::equals(type.fieldName(), "$polygon")) { return false; } BSONObjIterator coordIt(type.embeddedObject()); int vertices = 0; while (coordIt.more()) { BSONElement coord = coordIt.next(); if (!coord.isABSONObj()) { return false; } if (!isLegacyPoint(coord.Obj())) { return false; } ++vertices; } if (vertices < 3) { return false; } return true; }
void BSONCollectionCatalogEntry::MetaData::parse(const BSONObj& obj) { ns = obj["ns"].valuestrsafe(); if (obj["options"].isABSONObj()) { options.parse(obj["options"].Obj()); } BSONElement e = obj["indexes"]; if (e.isABSONObj()) { std::vector<BSONElement> entries = e.Array(); for (unsigned i = 0; i < entries.size(); i++) { BSONObj idx = entries[i].Obj(); IndexMetaData imd; imd.spec = idx["spec"].Obj().getOwned(); imd.ready = idx["ready"].trueValue(); if (idx.hasField("head")) { imd.head = RecordId(idx["head"].Long()); } else { imd.head = RecordId(idx["head_a"].Int(), idx["head_b"].Int()); } imd.multikey = idx["multikey"].trueValue(); indexes.push_back(imd); } } }
static void printData( const BSONObj& o , const BSONObj& headers ) { BSONObjIterator i(headers); while ( i.more() ) { BSONElement e = i.next(); BSONObj h = e.Obj(); int w = h["width"].numberInt(); BSONElement data; { BSONElement temp = o[e.fieldName()]; if ( temp.isABSONObj() ) data = temp.Obj()["data"]; } if ( data.type() == String ) cout << setw(w) << data.String(); else if ( data.type() == NumberDouble ) cout << setw(w) << setprecision(3) << data.number(); else if ( data.type() == NumberInt ) cout << setw(w) << data.numberInt(); else if ( data.eoo() ) cout << setw(w) << ""; else cout << setw(w) << "???"; cout << ' '; } cout << endl; }
bool parseLegacy(const BSONObj &obj, QueryGeometry *out, bool *isNear, bool *intersect, double *maxDistance) const { // Legacy intersect parsing: t.find({ loc : [0,0] }) if (out->parseFrom(obj)) { *isNear = true; return true; } bool ret = false; BSONObjIterator it(obj); while (it.more()) { BSONElement e = it.next(); if (!e.isABSONObj()) { return false; } BSONObj embeddedObj = e.embeddedObject(); // Legacy near parsing: t.find({ loc : { $near: [0,0], $maxDistance: 3 }}) // Legacy near parsing: t.find({ loc : { $near: [0,0] }}) if (mongoutils::str::equals(e.fieldName(), "$near")) { if (out->parseFrom(embeddedObj)) { uassert(16573, "near requires point, given " + embeddedObj.toString(), GeoParser::isPoint(embeddedObj)); *isNear = true; ret = true; } } else if (mongoutils::str::equals(e.fieldName(), "$maxDistance")) { *maxDistance = e.Number(); } } return ret; }
Status LiteParsedQuery::init(const string& ns, int ntoskip, int ntoreturn, int queryOptions, const BSONObj& queryObj, const BSONObj& proj, bool fromQueryMessage) { _ns = ns; _ntoskip = ntoskip; _ntoreturn = ntoreturn; _options = queryOptions; _proj = proj.getOwned(); if (_ntoskip < 0) { return Status(ErrorCodes::BadValue, "bad skip value in query"); } if (_ntoreturn < 0) { // _ntoreturn greater than zero is simply a hint on how many objects to send back per // "cursor batch". A negative number indicates a hard limit. _wantMore = false; _ntoreturn = -_ntoreturn; } if (fromQueryMessage) { BSONElement queryField = queryObj["query"]; if (!queryField.isABSONObj()) { queryField = queryObj["$query"]; } if (queryField.isABSONObj()) { _filter = queryField.embeddedObject().getOwned(); Status status = initFullQuery(queryObj); if (!status.isOK()) { return status; } } else { // TODO: Does this ever happen? _filter = queryObj.getOwned(); } } else { // This is the debugging code path. _filter = queryObj.getOwned(); } _hasReadPref = queryObj.hasField("$readPreference"); if (!isValidSortOrder(_sort)) { return Status(ErrorCodes::BadValue, "bad sort specification"); } _sort = normalizeSortOrder(_sort); return Status::OK(); }
// Entry point for a search. virtual shared_ptr<Cursor> newCursor(const BSONObj& query, const BSONObj& order, int numWanted) const { vector<QueryGeometry> regions; double maxDistance = DBL_MAX; bool isNear = false; bool isIntersect = false; // Go through the fields that we index, and for each geo one, make a QueryGeometry // object for the S2Cursor class to do intersection testing/cover generating with. for (size_t i = 0; i < _fields.size(); ++i) { const IndexedField &field = _fields[i]; if (IndexedField::GEO != field.type) { continue; } BSONElement e = query.getFieldDotted(field.name); if (e.eoo()) { continue; } if (!e.isABSONObj()) { continue; } BSONObj obj = e.Obj(); QueryGeometry geoQueryField(field.name); if (parseLegacy(obj, &geoQueryField, &isNear, &isIntersect, &maxDistance)) { regions.push_back(geoQueryField); } else if (parseQuery(obj, &geoQueryField, &isNear, &isIntersect, &maxDistance)) { regions.push_back(geoQueryField); } else { uasserted(16535, "can't parse query for *2d geo search: " + obj.toString()); } } if (isNear && isIntersect ) { uasserted(16474, "Can't do both near and intersect, query: " + query.toString()); } // I copied this from 2d.cpp. Guard against perversion. if (numWanted < 0) numWanted *= -1; if (0 == numWanted) numWanted = INT_MAX; BSONObjBuilder geoFieldsToNuke; for (size_t i = 0; i < _fields.size(); ++i) { const IndexedField &field = _fields[i]; if (IndexedField::GEO != field.type) { continue; } geoFieldsToNuke.append(field.name, ""); } // false means we want to filter OUT geoFieldsToNuke, not filter to include only that. BSONObj filteredQuery = query.filterFieldsUndotted(geoFieldsToNuke.obj(), false); if (isNear) { S2NearCursor *cursor = new S2NearCursor(keyPattern(), getDetails(), filteredQuery, regions, _params, numWanted, maxDistance); return shared_ptr<Cursor>(cursor); } else { // Default to intersect. S2Cursor *cursor = new S2Cursor(keyPattern(), getDetails(), filteredQuery, regions, _params, numWanted); return shared_ptr<Cursor>(cursor); } }
void MongoSchema::process(){ //std::cout << "Processing " << m_dbname << "." << m_col << std::endl; std::string querystr; querystr.clear(); querystr.append(m_dbname); querystr.append("."); querystr.append(m_col); int recordscount = m_conn->count(querystr); //std::cout << "count:" << recordscount << std::endl; std::auto_ptr<mongo::DBClientCursor> cursor = m_conn->query(querystr, mongo::Query()); //std::set<std::string> fields; while(cursor->more()){ mongo::BSONObj bo = cursor->next(); for( BSONObj::iterator i = bo.begin(); i.more(); ) { BSONElement e = i.next(); if(skipField(e.fieldName())){ continue; } if(e.isSimpleType()){ hashmap::const_iterator keyexsit = m_map.find(e.fieldName()); SchemaModel* sm = new SchemaModel(); if(keyexsit != m_map.end()){ sm = &m_map[e.fieldName()]; sm->count ++; }else{ sm->count = 1; sm->datatype = getType(e); m_map[e.fieldName()] = *sm; } }else if(e.isABSONObj()){ int depth = 0; std::string parent = e.fieldName(); extractBSON(e.Obj(), depth, parent); } } } BSONObjBuilder bOb; BSONArrayBuilder bArr; std::tr1::hash<std::string> hashfunc = m_map.hash_function(); for( hashmap::const_iterator i = m_map.begin(), e = m_map.end() ; i != e ; ++i ) { SchemaModel sm = i->second; float percentage = (float)sm.count / (float)recordscount * 100.0; std::cout.precision(4); BSONObj bo = BSON( "field" << i->first << "percent" << percentage << "datatype" << sm.datatype ); bArr.append(bo); //std::cout << i->first << " -> "<< "Percent: "<< percentage << " (hash = " << hashfunc( i->first ) << ")" << "\r\n"; } bOb.append(m_col, bArr.arr()); m_schema = bOb.obj(); }
bool GeoParser::isLegacyCenter(const BSONObj &obj) { BSONObjIterator objIt(obj); BSONElement center = objIt.next(); if (!center.isABSONObj()) { return false; } if (!isLegacyPoint(center.Obj())) { return false; } if (!objIt.more()) { return false; } BSONElement radius = objIt.next(); if (!radius.isNumber()) { return false; } return true; }
bool GeoMatchExpression::matchesSingleElement( const BSONElement& e ) const { if ( !e.isABSONObj()) return false; GeometryContainer container; if ( !container.parseFrom( e.Obj() ) ) return false; return _query.satisfiesPredicate( container ); }