// static bool CanonicalQuery::isSimpleIdQuery(const BSONObj& query) { bool hasID = false; BSONObjIterator it(query); while (it.more()) { BSONElement elt = it.next(); if (str::equals("_id", elt.fieldName())) { // Verify that the query on _id is a simple equality. hasID = true; if (elt.type() == Object) { // If the value is an object, it can't have a query operator // (must be a literal object match). if (elt.Obj().firstElementFieldName()[0] == '$') { return false; } } else if (!elt.isSimpleType() && BinData != elt.type()) { // The _id fild cannot be something like { _id : { $gt : ... // But it can be BinData. return false; } } else if (elt.fieldName()[0] == '$' && (str::equals("$isolated", elt.fieldName()) || str::equals("$atomic", elt.fieldName()))) { // ok, passthrough } else { // If the field is not _id, it must be $isolated/$atomic. return false; } } return hasID; }
// Copied verbatim from queryutil.cpp. static bool isSimpleIdQuery(const BSONObj& query) { BSONObjIterator it(query); if (!it.more()) { return false; } BSONElement elt = it.next(); if (it.more()) { return false; } if (strcmp("_id", elt.fieldName()) != 0) { return false; } // e.g. not something like { _id : { $gt : ... if (elt.isSimpleType()) { return true; } if (elt.type() == Object) { return elt.Obj().firstElementFieldName()[0] != '$'; } return false; }
// Copied verbatim from queryutil.cpp. static bool isSimpleIdQuery(const BSONObj& query) { // Just one field name. BSONObjIterator it(query); if (!it.more()) { return false; } BSONElement elt = it.next(); if (it.more()) { return false; } // Which is _id... if (strcmp("_id", elt.fieldName()) != 0) { return false; } // And not something like { _id : { $gt : ... if (elt.isSimpleType()) { return true; } // BinData is OK too. if (BinData == elt.type()) { return true; } // And if the value is an object... if (elt.type() == Object) { // Can't do this. return elt.Obj().firstElementFieldName()[0] != '$'; } return false; }
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(); }
int MongoSchema::extractBSON(mongo::BSONObj bo, int& depth, std::string parent){ if(depth >= m_depth){ return 0; } depth++; for( BSONObj::iterator i = bo.begin(); i.more(); ) { BSONElement e = i.next(); if(skipField(e.fieldName())){ continue; } std::string fieldname = parent ; fieldname.append("."); fieldname.append(e.fieldName()); if(e.isSimpleType()){ hashmap::const_iterator keyexsit = m_map.find(fieldname); SchemaModel* sm = new SchemaModel(); if(keyexsit != m_map.end()){ sm = &m_map[fieldname]; sm->count ++; }else{ sm->count = 1; sm->datatype = getType(e); m_map[fieldname] = *sm; } }else if(e.isABSONObj()){ extractBSON(e.Obj(), depth, fieldname); } } return 0; }