mongodb是一款文档型的非关系型数据库,性能非常高,老赵做过相关测试,我测试下来也差不多,和sql server相比,写入性能好太多了,下面是我的测试结果:

一条记录4K,1000万的数据占50G磁盘包括索引

Document doc = new Document();

doc.Add("Name", "Joseph" + DateTime.Now.Second);  索引

doc.Add("Age", r.Next(20, 50));  索引

doc.Add("Time", DateTime.Now);

doc.Add("Data", s);

记录很少的时候写吞吐5000左右

记录很少的时候基于索引的搜索每秒2000左右

数据很少的时候读吞吐每秒1400

数据很少的时候4M数据获取大概237毫秒

数据很少的时候搜索对写入影响不大

数据很少的时候读写相互影响不大

数据很多的时候

写入速度下降一半

读取速度没区别

搜索慢了很多,千万数据200毫秒的搜索速度,2个字段

读取对写入影响还是不大

查询对写入影响很大

另 不管数据量多少CPU始终在10%以下,内存随着数据量增多从20% - 80%

查询:

Document doc = new Document();
doc.Add("Name", "Joseph10");
doc.Add("Age", new Document().Append("$gte", 30).Append("$lte", 40));

读取:

table.FindOne(new Document());

测试程序点击这里下载。测试基于单个master的mongodb,后续测试发现,如果开启master/slave的话,写入速度非常不稳定,在向slave传送数据的时候写入速度下降50%到80%。还有就是mongodb随着并发的上升并没有带来写入速度上的提高,反而下降了一点,可能是因为读写锁的关系。

另外,点击这里下载一个查看mongodb对象的小工具(基于MongoDB.Driver.dll):

列出服务器

列出数据库 表 索引

服务器属性

数据库属性

表属性

列数据

通过写这个工具我觉得,Document使用树形来表示还是很方便的。

我还在想怎么通过类似sql语句的方式查询mongodb,找到了一个gudusoft.gsqlparser,可以解析各种sql,拿来一用,点击这里下载通过sql语句操作mongodb的测试工具,这个工具还是非常原始的版本,只能进行最简单的crud,select不支持group having等子句:

其实把这些小工具组合在一起就是一个简单的mongodb客户管理工具。

在 http://www.mongodb.org/display/DOCS/List+of+Database+Commands 上作者列出了所有db的命令,我们可以通过提交command操作。

在 http://www.mongodb.org/display/DOCS/DBA+Operations+from+the+Shell 上作者列出了可以在mongod工具中做的一些操作,其实这些操作完全可以通过提交command来进行,因为mongod工具完全就是一个javascript写的,我们看一下源代码中的mongo_vstudio.cpp:

const char * jsconcatcode = "__quiet = false;\n""chatty = function(s){\n""if ( ! __quiet )\n""print( s );}\n""friendlyEqual = function( a , b ){\n""if ( a == b )\n""return true;\n""if ( tojson( a ) == tojson( b ) )\n""return true;\n""return false;}\n""doassert = function( msg ){\n""print( \"assert: \" + msg );\n""throw msg;}\n""assert = function( b , msg ){\n""if ( assert._debug && msg ) print( \"in assert for: \" + msg );\n""if ( b )\n""return;\n""doassert( \"assert failed : \" + msg );}\n""assert._debug = false;\n""assert.eq = function( a , b , msg ){\n""if ( assert._debug && msg ) print( \"in assert for: \" + msg );\n""if ( a == b )\n""return;\n""if ( ( a != null && b != null ) && friendlyEqual( a , b ) )\n""return;\n""doassert( \"[\" + tojson( a ) + \"] != [\" + tojson( b ) + \"] are not equal : \" + msg );}\n""assert.neq = function( a , b , msg ){\n""if ( assert._debug && msg ) print( \"in assert for: \" + msg );\n""if ( a != b )\n""return;\n""doassert( \"[\" + a + \"] != [\" + b + \"] are equal : \" + msg );}\n""assert.soon = function( f, msg, timeout, interval ) {\n""if ( assert._debug && msg ) print( \"in assert for: \" + msg );\n""var start = new Date();\n""timeout = timeout || 30000;\n""interval = interval || 200;\n""var last;\n""while( 1 ) {\n""if ( typeof( f ) == \"string\" ){\n""if ( eval( f ) )\n""return;}\n""else {\n""if ( f() )\n""return;}\n""if ( ( new Date() ).getTime() - start.getTime() > timeout )\n""doassert( \"assert.soon failed: \" + f + \", msg:\" + msg );\n""sleep( interval );}}\n""assert.throws = function( func , params , msg ){\n""if ( assert._debug && msg ) print( \"in assert for: \" + msg );\n""try {\n""func.apply( null , params );}\n""catch ( e ){\n""return e;}\n""doassert( \"did not throw exception: \" + msg );}\n""assert.commandWorked = function( res , msg ){\n""if ( assert._debug && msg ) print( \"in assert for: \" + msg );\n""if ( res.ok == 1 )\n""return;\n""doassert( \"command failed: \" + tojson( res ) + \" : \" + msg );}\n""assert.commandFailed = function( res , msg ){\n""if ( assert._debug && msg ) print( \"in assert for: \" + msg );\n""if ( res.ok == 0 )\n""return;\n""doassert( \"command worked when it should have failed: \" + tojson( res ) + \" : \" + msg );}\n""assert.isnull = function( what , msg ){\n""if ( assert._debug && msg ) print( \"in assert for: \" + msg );\n""if ( what == null )\n""return;\n""doassert( \"supposed to null (\" + ( msg || \"\" ) + \") was: \" + tojson( what ) );}\n""assert.lt = function( a , b , msg ){\n""if ( assert._debug && msg ) print( \"in assert for: \" + msg );\n""if ( a < b )\n""return;\n""doassert( a + \" is not less than \" + b + \" : \" + msg );}\n""assert.gt = function( a , b , msg ){\n""if ( assert._debug && msg ) print( \"in assert for: \" + msg );\n""if ( a > b )\n""return;\n""doassert( a + \" is not greater than \" + b + \" : \" + msg );}\n""assert.close = function( a , b , msg ){\n""var diff = Math.abs( (a-b)/((a+b)/2) );\n""if ( diff < .001 )\n""return;\n""doassert( a + \" is not close to \" + b + \" diff: \" + diff + \" : \" + msg );}\n""Object.extend = function( dst , src , deep ){\n""for ( var k in src ){\n""var v = src[k];\n""if ( deep && typeof(v) == \"object\" ){\n""v = Object.extend( typeof ( v.length ) == \"number\" ? [] : {} , v , true );}\n""dst[k] = v;}\n""return dst;}\n""argumentsToArray = function( a ){\n""var arr = [];\n""for ( var i=0; i<a.length; i++ )\n""arr[i] = a[i];\n""return arr;}\n""isString = function( x ){\n""return typeof( x ) == \"string\";}\n""isNumber = function(x){\n""return typeof( x ) == \"number\";}\n""isObject = function( x ){\n""return typeof( x ) == \"object\";}\n""String.prototype.trim = function() {\n""return this.replace(/^\\s+|\\s+$/g,\"\");}\n""String.prototype.ltrim = function() {\n""return this.replace(/^\\s+/,\"\");}\n""String.prototype.rtrim = function() {\n""return this.replace(/\\s+$/,\"\");}\n""Date.timeFunc = function( theFunc , numTimes ){\n""var start = new Date();\n""numTimes = numTimes || 1;\n""for ( var i=0; i<numTimes; i++ ){\n""theFunc.apply( null , argumentsToArray( arguments ).slice( 2 ) );}\n""return (new Date()).getTime() - start.getTime();}\n""Date.prototype.tojson = function(){\n""return \"\\\"\" + this.toString() + \"\\\"\";}\n""RegExp.prototype.tojson = RegExp.prototype.toString;\n""Array.contains = function( a  , x ){\n""for ( var i=0; i<a.length; i++ ){\n""if ( a[i] == x )\n""return true;}\n""return false;}\n""Array.unique = function( a ){\n""var u = [];\n""for ( var i=0; i<a.length; i++){\n""var o = a[i];\n""if ( ! Array.contains( u , o ) ){\n""u.push( o );}}\n""return u;}\n""Array.shuffle = function( arr ){\n""for ( var i=0; i<arr.length-1; i++ ){\n""var pos = i+Random.randInt(arr.length-i);\n""var save = arr[i];\n""arr[i] = arr[pos];\n""arr[pos] = save;}\n""return arr;}\n""Array.tojson = function( a , indent ){\n""if (!indent)\n""indent = \"\";\n""if (a.length == 0) {\n""return \"[ ]\";}\n""var s = \"[\\n\";\n""indent += \"\\t\";\n""for ( var i=0; i<a.length; i++){\n""s += indent + tojson( a[i], indent );\n""if ( i < a.length - 1 ){\n""s += \",\\n\";}}\n""if ( a.length == 0 ) {\n""s += indent;}\n""indent = indent.substring(1);\n""s += \"\\n\"+indent+\"]\";\n""return s;}\n""Array.fetchRefs = function( arr , coll ){\n""var n = [];\n""for ( var i=0; i<arr.length; i ++){\n""var z = arr[i];\n""if ( coll && coll != z.getCollection() )\n""continue;\n""n.push( z.fetch() );}\n""return n;}\n""Array.sum = function( arr ){\n""if ( arr.length == 0 )\n""return null;\n""var s = arr[0];\n""for ( var i=1; i<arr.length; i++ )\n""s += arr[i];\n""return s;}\n""Array.avg = function( arr ){\n""if ( arr.length == 0 )\n""return null;\n""return Array.sum( arr ) / arr.length;}\n""Array.stdDev = function( arr ){\n""var avg = Array.avg( arr );\n""var sum = 0;\n""for ( var i=0; i<arr.length; i++ ){\n""sum += Math.pow( arr[i] - avg , 2 );}\n""return Math.sqrt( sum / arr.length );}\n""Object.keySet = function( o ) {\n""var ret = new Array();\n""for( i in o ) {\n""if ( !( i in o.__proto__ && o[ i ] === o.__proto__[ i ] ) ) {\n""ret.push( i );}}\n""return ret;}\n""if ( ! ObjectId.prototype )\n""ObjectId.prototype = {}\n""ObjectId.prototype.toString = function(){\n""return this.str;}\n""ObjectId.prototype.tojson = function(){\n""return \"ObjectId(\\\"\" + this.str + \"\\\")\";}\n""ObjectId.prototype.isObjectId = true;\n""if ( typeof( DBPointer ) != \"undefined\" ){\n""DBPointer.prototype.fetch = function(){\n""assert( this.ns , \"need a ns\" );\n""assert( this.id , \"need an id\" );\n""return db[ this.ns ].findOne( { _id : this.id } );}\n""DBPointer.prototype.tojson = function(indent){\n""return tojson({\"ns\" : this.ns, \"id\" : this.id}, indent);}\n""DBPointer.prototype.getCollection = function(){\n""return this.ns;}\n""DBPointer.prototype.toString = function(){\n""return \"DBPointer \" + this.ns + \":\" + this.id;}}\n""else {\n""print( \"warning: no DBPointer\" );}\n""if ( typeof( DBRef ) != \"undefined\" ){\n""DBRef.prototype.fetch = function(){\n""assert( this.$ref , \"need a ns\" );\n""assert( this.$id , \"need an id\" );\n""return db[ this.$ref ].findOne( { _id : this.$id } );}\n""DBRef.prototype.tojson = function(indent){\n""return tojson({\"$ref\" : this.$ref, \"$id\" : this.$id}, indent);}\n""DBRef.prototype.getCollection = function(){\n""return this.$ref;}\n""DBRef.prototype.toString = function(){\n""return this.tojson();}}\n""else {\n""print( \"warning: no DBRef\" );}\n""if ( typeof( BinData ) != \"undefined\" ){\n""BinData.prototype.tojson = function(){\n""return \"BinData type: \" + this.type + \" len: \" + this.len;}}\n""else {\n""print( \"warning: no BinData\" );}\n""if ( typeof _threadInject != \"undefined\" ){\n""print( \"fork() available!\" );\n""Thread = function(){\n""this.init.apply( this, arguments );}\n""_threadInject( Thread.prototype );\n""ScopedThread = function() {\n""this.init.apply( this, arguments );}\n""ScopedThread.prototype = new Thread( function() {} );\n""_scopedThreadInject( ScopedThread.prototype );\n""fork = function() {\n""var t = new Thread( function() {} );\n""Thread.apply( t, arguments );\n""return t;}\n""EventGenerator = function( me, collectionName, mean ) {\n""this.mean = mean;\n""this.events = new Array( me, collectionName );}\n""EventGenerator.prototype._add = function( action ) {\n""this.events.push( [ Random.genExp( this.mean ), action ] );}\n""EventGenerator.prototype.addInsert = function( obj ) {\n""this._add( \"t.insert( \" + tojson( obj ) + \" )\" );}\n""EventGenerator.prototype.addRemove = function( obj ) {\n""this._add( \"t.remove( \" + tojson( obj ) + \" )\" );}\n""EventGenerator.prototype.addUpdate = function( objOld, objNew ) {\n""this._add( \"t.update( \" + tojson( objOld ) + \", \" + tojson( objNew ) + \" )\" );}\n""EventGenerator.prototype.addCheckCount = function( count, query, shouldPrint, checkQuery ) {\n""query = query || {};\n""shouldPrint = shouldPrint || false;\n""checkQuery = checkQuery || false;\n""var action = \"assert.eq( \" + count + \", t.count( \" + tojson( query ) + \" ) );\"\n""if ( checkQuery ) {\n""action += \" assert.eq( \" + count + \", t.find( \" + tojson( query ) + \" ).toArray().length );\"}\n""if ( shouldPrint ) {\n""action += \" print( me + ' ' + \" + count + \" );\";}\n""this._add( action );}\n""EventGenerator.prototype.getEvents = function() {\n""return this.events;}\n""EventGenerator.dispatch = function() {\n""var args = argumentsToArray( arguments );\n""var me = args.shift();\n""var collectionName = args.shift();\n""var m = new Mongo( db.getMongo().host );\n""var t = m.getDB( \"test\" )[ collectionName ];\n""for( var i in args ) {\n""sleep( args[ i ][ 0 ] );\n""eval( args[ i ][ 1 ] );}}\n""ParallelTester = function() {\n""this.params = new Array();}\n""ParallelTester.prototype.add = function( fun, args ) {\n""args = args || [];\n""args.unshift( fun );\n""this.params.push( args );}\n""ParallelTester.prototype.run = function( msg, newScopes ) {\n""newScopes = newScopes || false;\n""assert.parallelTests( this.params, msg, newScopes );}\n""ParallelTester.createJstestsLists = function( n ) {\n""var params = new Array();\n""for( var i = 0; i < n; ++i ) {\n""params.push( [] );}\n""var makeKeys = function( a ) {\n""var ret = {};\n""for( var i in a ) {\n""ret[ a[ i ] ] = 1;}\n""return ret;}\n""var skipTests = makeKeys( [ \"jstests/dbadmin.js\",\n""\"jstests/repair.js\",\n""\"jstests/cursor8.js\",\n""\"jstests/recstore.js\",\n""\"jstests/extent.js\",\n""\"jstests/indexb.js\",\n""\"jstests/profile1.js\",\n""\"jstests/mr3.js\",\n""\"jstests/apitest_db.js\"] );\n""var serialTestsArr = [ \"jstests/fsync.js\",\n""\"jstests/fsync2.js\" ];\n""var serialTests = makeKeys( serialTestsArr );\n""params[ 0 ] = serialTestsArr;\n""var files = listFiles(\"jstests\");\n""files = Array.shuffle( files );\n""var i = 0;\n""files.forEach(\n""function(x) {\n""if ( /_runner/.test(x.name) ||\n""/_lodeRunner/.test(x.name) ||\n""( x.name in skipTests ) ||\n""( x.name in serialTests ) ||\n""! /\\.js$/.test(x.name ) ){\n""print(\" >>>>>>>>>>>>>>> skipping \" + x.name);\n""return;}\n""params[ i % n ].push( x.name );\n""++i;}\n"");\n""params[ 0 ] = Array.shuffle( params[ 0 ] );\n""for( var i in params ) {\n""params[ i ].unshift( i );}\n""return params;}\n""ParallelTester.fileTester = function() {\n""var args = argumentsToArray( arguments );\n""var suite = args.shift();\n""args.forEach(\n""function( x ) {\n""print(\"         S\" + suite + \" Test : \" + x + \" ...\");\n""var time = Date.timeFunc( function() { load(x); }, 1);\n""print(\"         S\" + suite + \" Test : \" + x + \" \" + time + \"ms\" );}\n"");}\n""assert.parallelTests = function( params, msg, newScopes ) {\n""newScopes = newScopes || false;\n""var wrapper = function( fun, argv ) {\n""eval (\n""\"var z = function() {\" +\n""\"var __parallelTests__fun = \" + fun.toString() + \";\" +\n""\"var __parallelTests__argv = \" + tojson( argv ) + \";\" +\n""\"var __parallelTests__passed = false;\" +\n""\"try {\" +\n""\"__parallelTests__fun.apply( 0, __parallelTests__argv );\" +\n""\"__parallelTests__passed = true;\" +\n""\"} catch ( e ) {\" +\n""\"print( e );\" +\n""\"}\" +\n""\"return __parallelTests__passed;\" +\n""\"}\"\n"");\n""return z;}\n""var runners = new Array();\n""for( var i in params ) {\n""var param = params[ i ];\n""var test = param.shift();\n""var t;\n""if ( newScopes )\n""t = new ScopedThread( wrapper( test, param ) );\n""else\n""t = new Thread( wrapper( test, param ) );\n""runners.push( t );}\n""runners.forEach( function( x ) { x.start(); } );\n""var nFailed = 0;\n""runners.forEach( function( x ) { if( !x.returnData() ) { ++nFailed; } } );\n""assert.eq( 0, nFailed, msg );}}\n""tojson = function( x, indent , nolint ){\n""if ( x === null )\n""return \"null\";\n""if ( x === undefined )\n""return \"undefined\";\n""if (!indent)\n""indent = \"\";\n""switch ( typeof x ){\n""case \"string\": {\n""var s = \"\\\"\";\n""for ( var i=0; i<x.length; i++ ){\n""if ( x[i] == '\"' ){\n""s += \"\\\\\\\"\";}\n""else\n""s += x[i];}\n""return s + \"\\\"\";}\n""case \"number\":\n""case \"boolean\":\n""return \"\" + x;\n""case \"object\":{\n""var s = tojsonObject( x, indent , nolint );\n""if ( ( nolint == null || nolint == true ) && s.length < 80 && ( indent == null || indent.length == 0 ) ){\n""s = s.replace( /[\\s\\r\\n ]+/gm , \" \" );}\n""return s;}\n""case \"function\":\n""return x.toString();\n""default:\n""throw \"tojson can't handle type \" + ( typeof x );}}\n""tojsonObject = function( x, indent , nolint ){\n""var lineEnding = nolint ? \" \" : \"\\n\";\n""var tabSpace = nolint ? \"\" : \"\\t\";\n""assert.eq( ( typeof x ) , \"object\" , \"tojsonObject needs object, not [\" + ( typeof x ) + \"]\" );\n""if (!indent)\n""indent = \"\";\n""if ( typeof( x.tojson ) == \"function\" && x.tojson != tojson ) {\n""return x.tojson(indent,nolint);}\n""if ( typeof( x.constructor.tojson ) == \"function\" && x.constructor.tojson != tojson ) {\n""return x.constructor.tojson( x, indent , nolint );}\n""if ( x.toString() == \"[object MaxKey]\" )\n""return \"{ $maxKey : 1 }\";\n""if ( x.toString() == \"[object MinKey]\" )\n""return \"{ $minKey : 1 }\";\n""var s = \"{\" + lineEnding;\n""indent += tabSpace;\n""var total = 0;\n""for ( var k in x ) total++;\n""if ( total == 0 ) {\n""s += indent + lineEnding;}\n""var keys = x;\n""if ( typeof( x._simpleKeys ) == \"function\" )\n""keys = x._simpleKeys();\n""var num = 1;\n""for ( var k in keys ){\n""var val = x[k];\n""if ( val == DB.prototype || val == DBCollection.prototype )\n""continue;\n""s += indent + \"\\\"\" + k + \"\\\" : \" + tojson( val, indent , nolint );\n""if (num != total) {\n""s += \",\";\n""num++;}\n""s += lineEnding;}\n""indent = indent.substring(1);\n""return s + indent + \"}\";}\n""shellPrint = function( x ){\n""it = x;\n""if ( x != undefined )\n""shellPrintHelper( x );\n""if ( db ){\n""var e = db.getPrevError();\n""if ( e.err ) {\n""if( e.nPrev <= 1 )\n""print( \"error on last call: \" + tojson( e.err ) );\n""else\n""print( \"an error \" + tojson(e.err) + \" occurred \" + e.nPrev + \" operations back in the command invocation\" );}\n""db.resetError();}}\n""printjson = function(x){\n""print( tojson( x ) );}\n""shellPrintHelper = function( x ){\n""if ( typeof( x ) == \"undefined\" ){\n""if ( typeof( db ) != \"undefined\" && db.getLastError ){\n""var e = db.getLastError();\n""if ( e != null )\n""print( e );}\n""return;}\n""if ( x == null ){\n""print( \"null\" );\n""return;}\n""if ( typeof x != \"object\" )\n""return print( x );\n""var p = x.shellPrint;\n""if ( typeof p == \"function\" )\n""return x.shellPrint();\n""var p = x.tojson;\n""if ( typeof p == \"function\" )\n""print( x.tojson() );\n""else\n""print( tojson( x ) );}\n""shellHelper = function( command , rest , shouldPrint ){\n""command = command.trim();\n""var args = rest.trim().replace(/;$/,\"\").split( \"\\s+\" );\n""if ( ! shellHelper[command] )\n""throw \"no command [\" + command + \"]\";\n""var res = shellHelper[command].apply( null , args );\n""if ( shouldPrint ){\n""shellPrintHelper( res );}\n""return res;}\n""help = shellHelper.help = function(){\n""print( \"HELP\" );\n""print( \"\\t\" + \"show dbs                     show database names\");\n""print( \"\\t\" + \"show collections             show collections in current database\");\n""print( \"\\t\" + \"show users                   show users in current database\");\n""print( \"\\t\" + \"show profile                 show most recent system.profile entries with time >= 1ms\");\n""print( \"\\t\" + \"use <db name>                set curent database to <db name>\" );\n""print( \"\\t\" + \"db.help()                    help on DB methods\");\n""print( \"\\t\" + \"db.foo.help()                help on collection methods\");\n""print( \"\\t\" + \"db.foo.find()                list objects in collection foo\" );\n""print( \"\\t\" + \"db.foo.find( { a : 1 } )     list objects in foo where a == 1\" );\n""print( \"\\t\" + \"it                           result of the last line evaluated; use to further iterate\");}\n""shellHelper.use = function( dbname ){\n""db = db.getMongo().getDB( dbname );\n""print( \"switched to db \" + db.getName() );}\n""shellHelper.it = function(){\n""if ( typeof( ___it___ ) == \"undefined\" || ___it___ == null ){\n""print( \"no cursor\" );\n""return;}\n""shellPrintHelper( ___it___ );}\n""shellHelper.show = function( what ){\n""assert( typeof what == \"string\" );\n""if( what == \"profile\" ) {\n""if( db.system.profile.count() == 0 ) {\n""print(\"db.system.profile is empty\");\n""print(\"Use db.setProfilingLevel(2) will enable profiling\");\n""print(\"Use db.system.profile.find() to show raw profile entries\");}\n""else {\n""print();\n""db.system.profile.find({ millis : { $gt : 0 } }).sort({$natural:-1}).limit(5).forEach( function(x){print(\"\"+x.millis+\"ms \" + String(x.ts).substring(0,24)); print(x.info); print(\"\\n\");} )}\n""return \"\";}\n""if ( what == \"users\" ){\n""db.system.users.find().forEach( printjson );\n""return \"\";}\n""if ( what == \"collections\" || what == \"tables\" ) {\n""db.getCollectionNames().forEach( function(x){print(x)} );\n""return \"\";}\n""if ( what == \"dbs\" ) {\n""db.getMongo().getDBNames().sort().forEach( function(x){print(x)} );\n""return \"\";}\n""throw \"don't know how to show [\" + what + \"]\";}\n""if ( typeof( Map ) == \"undefined\" ){\n""Map = function(){\n""this._data = {};}}\n""Map.hash = function( val ){\n""if ( ! val )\n""return val;\n""switch ( typeof( val ) ){\n""case 'string':\n""case 'number':\n""case 'date':\n""return val.toString();\n""case 'object':\n""case 'array':\n""var s = \"\";\n""for ( var k in val ){\n""s += k + val[k];}\n""return s;}\n""throw \"can't hash : \" + typeof( val );}\n""Map.prototype.put = function( key , value ){\n""var o = this._get( key );\n""var old = o.value;\n""o.value = value;\n""return old;}\n""Map.prototype.get = function( key ){\n""return this._get( key ).value;}\n""Map.prototype._get = function( key ){\n""var h = Map.hash( key );\n""var a = this._data[h];\n""if ( ! a ){\n""a = [];\n""this._data[h] = a;}\n""for ( var i=0; i<a.length; i++ ){\n""if ( friendlyEqual( key , a[i].key ) ){\n""return a[i];}}\n""var o = { key : key , value : null };\n""a.push( o );\n""return o;}\n""Map.prototype.values = function(){\n""var all = [];\n""for ( var k in this._data ){\n""this._data[k].forEach( function(z){ all.push( z.value ); } );}\n""return all;}\n""if ( typeof( gc ) == \"undefined\" ){\n""gc = function(){}}\n""Math.sigFig = function( x , N ){\n""if ( ! N ){\n""N = 3;}\n""var p = Math.pow( 10, N - Math.ceil( Math.log( Math.abs(x) ) / Math.log( 10 )) );\n""return Math.round(x*p)/p;}\n""Random = function() {}\n""Random.srand = function( s ) { _srand( s ); }\n""Random.rand = function() { return _rand(); }\n""Random.randInt = function( n ) { return Math.floor( Random.rand() * n ); }\n""Random.setRandomSeed = function( s ) {\n""s = s || new Date().getTime();\n""print( \"setting random seed: \" + s );\n""Random.srand( s );}\n""Random.genExp = function( mean ) {\n""return -Math.log( Random.rand() ) * mean;}\n""killWithUris = function( uris ) {\n""var inprog = db.currentOp().inprog;\n""for( var u in uris ) {\n""for ( var i in inprog ) {\n""if ( uris[ u ] == inprog[ i ].client ) {\n""db.killOp( inprog[ i ].opid );}}}}\n""if ( typeof DB == \"undefined\" ){\n""DB = function( mongo , name ){\n""this._mongo = mongo;\n""this._name = name;}}\n""DB.prototype.getMongo = function(){\n""assert( this._mongo , \"why no mongo!\" );\n""return this._mongo;}\n""DB.prototype.getSisterDB = function( name ){\n""return this.getMongo().getDB( name );}\n""DB.prototype.getName = function(){\n""return this._name;}\n""DB.prototype.stats = function(){\n""return this.runCommand( { dbstats : 1 } );}\n""DB.prototype.getCollection = function( name ){\n""return new DBCollection( this._mongo , this , name , this._name + \".\" + name );}\n""DB.prototype.commandHelp = function( name ){\n""var c = {};\n""c[name] = 1;\n""c.help = true;\n""return this.runCommand( c ).help;}\n""DB.prototype.runCommand = function( obj ){\n""if ( typeof( obj ) == \"string\" ){\n""var n = {};\n""n[obj] = 1;\n""obj = n;}\n""return this.getCollection( \"$cmd\" ).findOne( obj );}\n""DB.prototype._dbCommand = DB.prototype.runCommand;\n""DB.prototype._adminCommand = function( obj ){\n""if ( this._name == \"admin\" )\n""return this.runCommand( obj );\n""return this.getSisterDB( \"admin\" ).runCommand( obj );}\n""DB.prototype.addUser = function( username , pass, readOnly ){\n""readOnly = readOnly || false;\n""var c = this.getCollection( \"system.users\" );\n""var u = c.findOne( { user : username } ) || { user : username };\n""u.readOnly = readOnly;\n""u.pwd = hex_md5( username + \":mongo:\" + pass );\n""print( tojson( u ) );\n""c.save( u );}\n""DB.prototype.removeUser = function( username ){\n""this.getCollection( \"system.users\" ).remove( { user : username } );}\n""DB.prototype.__pwHash = function( nonce, username, pass ) {\n""return hex_md5( nonce + username + hex_md5( username + \":mongo:\" + pass ) );}\n""DB.prototype.auth = function( username , pass ){\n""var n = this.runCommand( { getnonce : 1 } );\n""var a = this.runCommand(\n""{\n""authenticate : 1 ,\n""user : username ,\n""nonce : n.nonce ,\n""key : this.__pwHash( n.nonce, username, pass )}\n"");\n""return a.ok;}\n""\n""DB.prototype.createCollection = function(name, opt) {\n""var options = opt || {};\n""var cmd = { create: name, capped: options.capped, size: options.size, max: options.max };\n""var res = this._dbCommand(cmd);\n""return res;}\n""\n""DB.prototype.getProfilingLevel  = function() {\n""var res = this._dbCommand( { profile: -1 } );\n""return res ? res.was : null;}\n""\n""DB.prototype.dropDatabase = function() {\n""if ( arguments.length )\n""throw \"dropDatabase doesn't take arguments\";\n""return this._dbCommand( { dropDatabase: 1 } );}\n""DB.prototype.shutdownServer = function() {\n""if( \"admin\" != this._name ){\n""return \"shutdown command only works with the admin database; try 'use admin'\";}\n""try {\n""var res = this._dbCommand(\"shutdown\");\n""if( res )\n""throw \"shutdownServer failed: \" + res.errmsg;\n""throw \"shutdownServer failed\";}\n""catch ( e ){\n""assert( tojson( e ).indexOf( \"error doing query: failed\" ) >= 0 , \"unexpected error: \" + tojson( e ) );\n""print( \"server should be down...\" );}}\n""\n""DB.prototype.cloneDatabase = function(from) {\n""assert( isString(from) && from.length );\n""return this._dbCommand( { clone: from } );}\n""\n""DB.prototype.cloneCollection = function(from, collection, query) {\n""assert( isString(from) && from.length );\n""assert( isString(collection) && collection.length );\n""collection = this._name + \".\" + collection;\n""query = query || {};\n""return this._dbCommand( { cloneCollection:collection, from:from, query:query } );}\n""\n""DB.prototype.copyDatabase = function(fromdb, todb, fromhost, username, password) {\n""assert( isString(fromdb) && fromdb.length );\n""assert( isString(todb) && todb.length );\n""fromhost = fromhost || \"\";\n""if ( username && password ) {\n""var n = this._adminCommand( { copydbgetnonce : 1, fromhost:fromhost } );\n""return this._adminCommand( { copydb:1, fromhost:fromhost, fromdb:fromdb, todb:todb, username:username, nonce:n.nonce, key:this.__pwHash( n.nonce, username, password ) } );\n""} else {\n""return this._adminCommand( { copydb:1, fromhost:fromhost, fromdb:fromdb, todb:todb } );}}\n""\n""DB.prototype.repairDatabase = function() {\n""return this._dbCommand( { repairDatabase: 1 } );}\n""DB.prototype.help = function() {\n""print(\"DB methods:\");\n""print(\"\\tdb.addUser(username, password[,])\");\n""print(\"\\tdb.auth(username, password)\");\n""print(\"\\tdb.cloneDatabase(fromhost)\");\n""print(\"\\tdb.commandHelp(name) returns the help for the command\");\n""print(\"\\tdb.copyDatabase(fromdb, todb, fromhost)\");\n""print(\"\\tdb.createCollection(name, { size : ..., capped : ..., max : ... } )\");\n""print(\"\\tdb.currentOp() displays the current operation in the db\" );\n""print(\"\\tdb.dropDatabase()\");\n""print(\"\\tdb.eval(func, args) run code server-side\");\n""print(\"\\tdb.getCollection(cname) same as db['cname'] or db.cname\");\n""print(\"\\tdb.getCollectionNames()\");\n""print(\"\\tdb.getLastError() - just returns the err msg string\");\n""print(\"\\tdb.getLastErrorObj() - return full status object\");\n""print(\"\\tdb.getMongo() get the server connection object\");\n""print(\"\\tdb.getMongo().setSlaveOk() allow this connection to read from the nonmaster member of a replica pair\");\n""print(\"\\tdb.getName()\");\n""print(\"\\tdb.getPrevError()\");\n""print(\"\\tdb.getProfilingLevel()\");\n""print(\"\\tdb.getReplicationInfo()\");\n""print(\"\\tdb.getSisterDB(name) get the db at the same server as this onew\");\n""print(\"\\tdb.killOp(opid) kills the current operation in the db\" );\n""print(\"\\tdb.printCollectionStats()\" );\n""print(\"\\tdb.printReplicationInfo()\");\n""print(\"\\tdb.printSlaveReplicationInfo()\");\n""print(\"\\tdb.printShardingStatus()\");\n""print(\"\\tdb.removeUser(username)\");\n""print(\"\\tdb.repairDatabase()\");\n""print(\"\\tdb.resetError()\");\n""print(\"\\tdb.runCommand(cmdObj) run a database command.  if cmdObj is a string, turns it into { cmdObj : 1 }\");\n""print(\"\\tdb.setProfilingLevel(level,<slowms>) 0=off 1=slow 2=all\");\n""print(\"\\tdb.shutdownServer()\");\n""print(\"\\tdb.stats()\");\n""print(\"\\tdb.version() current version of the server\" );}\n""DB.prototype.printCollectionStats = function(){\n""var mydb = this;\n""this.getCollectionNames().forEach(\n""function(z){\n""print( z );\n""printjson( mydb.getCollection(z).stats() );\n""print( \"---\" );}\n"");}\n""\n""DB.prototype.setProfilingLevel = function(level,slowms) {\n""if (level < 0 || level > 2) {\n""throw { dbSetProfilingException : \"input level \" + level + \" is out of range [0..2]\" };}\n""var cmd = { profile: level };\n""if ( slowms )\n""cmd[\"slowms\"] = slowms;\n""return this._dbCommand( cmd );}\n""\n""DB.prototype.eval = function(jsfunction) {\n""var cmd = { $eval : jsfunction };\n""if ( arguments.length > 1 ) {\n""cmd.args = argumentsToArray( arguments ).slice(1);}\n""var res = this._dbCommand( cmd );\n""if (!res.ok)\n""throw tojson( res );\n""return res.retval;}\n""DB.prototype.dbEval = DB.prototype.eval;\n""\n""DB.prototype.groupeval = function(parmsObj) {\n""var groupFunction = function() {\n""var parms = args[0];\n""var c = db[parms.ns].find(parms.cond||{});\n""var map = new Map();\n""var pks = parms.key ? Object.keySet( parms.key ) : null;\n""var pkl = pks ? pks.length : 0;\n""var key = {};\n""while( c.hasNext() ) {\n""var obj = c.next();\n""if ( pks ) {\n""for( var i=0; i<pkl; i++ ){\n""var k = pks[i];\n""key[k] = obj[k];}}\n""else {\n""key = parms.$keyf(obj);}\n""var aggObj = map.get(key);\n""if( aggObj == null ) {\n""var newObj = Object.extend({}, key);\n""aggObj = Object.extend(newObj, parms.initial)\n""map.put( key , aggObj );}\n""parms.$reduce(obj, aggObj);}\n""return map.values();}\n""return this.eval(groupFunction, this._groupFixParms( parmsObj ));}\n""DB.prototype.groupcmd = function( parmsObj ){\n""var ret = this.runCommand( { \"group\" : this._groupFixParms( parmsObj ) } );\n""if ( ! ret.ok ){\n""throw \"group command failed: \" + tojson( ret );}\n""return ret.retval;}\n""DB.prototype.group = DB.prototype.groupcmd;\n""DB.prototype._groupFixParms = function( parmsObj ){\n""var parms = Object.extend({}, parmsObj);\n""if( parms.reduce ) {\n""parms.$reduce = parms.reduce;\n""delete parms.reduce;}\n""if( parms.keyf ) {\n""parms.$keyf = parms.keyf;\n""delete parms.keyf;}\n""return parms;}\n""DB.prototype.resetError = function(){\n""return this.runCommand( { reseterror : 1 } );}\n""DB.prototype.forceError = function(){\n""return this.runCommand( { forceerror : 1 } );}\n""DB.prototype.getLastError = function(){\n""var res = this.runCommand( { getlasterror : 1 } );\n""if ( ! res.ok )\n""throw \"getlasterror failed: \" + tojson( res );\n""return res.err;}\n""DB.prototype.getLastErrorObj = function(){\n""var res = this.runCommand( { getlasterror : 1 } );\n""if ( ! res.ok )\n""throw \"getlasterror failed: \" + tojson( res );\n""return res;}\n""DB.prototype.getLastErrorCmd = DB.prototype.getLastErrorObj;\n""/* Return the last error which has occurred, even if not the very last error.\n""Returns:\n""{ err : <error message>, nPrev : <how_many_ops_back_occurred>, ok : 1 }\n""result.err will be null if no error has occurred.\n""*/\n""DB.prototype.getPrevError = function(){\n""return this.runCommand( { getpreverror : 1 } );}\n""DB.prototype.getCollectionNames = function(){\n""var all = [];\n""var nsLength = this._name.length + 1;\n""this.getCollection( \"system.namespaces\" ).find().sort({name:1}).forEach(\n""function(z){\n""var name = z.name;\n""if ( name.indexOf( \"$\" ) >= 0 && name != \"local.oplog.$main\" )\n""return;\n""all.push( name.substring( nsLength ) );}\n"");\n""return all;}\n""DB.prototype.tojson = function(){\n""return this._name;}\n""DB.prototype.toString = function(){\n""return this._name;}\n""DB.prototype.currentOp = function(){\n""return db.$cmd.sys.inprog.findOne();}\n""DB.prototype.currentOP = DB.prototype.currentOp;\n""DB.prototype.killOp = function(op) {\n""if( !op )\n""throw \"no opNum to kill specified\";\n""return db.$cmd.sys.killop.findOne({'op':op});}\n""DB.prototype.killOP = DB.prototype.killOp;\n""DB.tsToSeconds = function(x){\n""if ( x.t && x.i )\n""return x.t / 1000;\n""return x / 4294967296;}\n""\n""DB.prototype.getReplicationInfo = function() {\n""var db = this.getSisterDB(\"local\");\n""var result = { };\n""var ol = db.system.namespaces.findOne({name:\"local.oplog.$main\"});\n""if( ol && ol.options ) {\n""result.logSizeMB = ol.options.size / 1000 / 1000;\n""} else {\n""result.errmsg  = \"local.oplog.$main, or its options, not found in system.namespaces collection (not --master?)\";\n""return result;}\n""var firstc = db.oplog.$main.find().sort({$natural:1}).limit(1);\n""var lastc = db.oplog.$main.find().sort({$natural:-1}).limit(1);\n""if( !firstc.hasNext() || !lastc.hasNext() ) {\n""result.errmsg = \"objects not found in local.oplog.$main -- is this a new and empty db instance?\";\n""result.oplogMainRowCount = db.oplog.$main.count();\n""return result;}\n""var first = firstc.next();\n""var last = lastc.next();\n""{\n""var tfirst = first.ts;\n""var tlast = last.ts;\n""if( tfirst && tlast ) {\n""tfirst = DB.tsToSeconds( tfirst );\n""tlast = DB.tsToSeconds( tlast );\n""result.timeDiff = tlast - tfirst;\n""result.timeDiffHours = Math.round(result.timeDiff / 36)/100;\n""result.tFirst = (new Date(tfirst*1000)).toString();\n""result.tLast  = (new Date(tlast*1000)).toString();\n""result.now = Date();}\n""else {\n""result.errmsg = \"ts element not found in oplog objects\";}}\n""return result;}\n""DB.prototype.printReplicationInfo = function() {\n""var result = this.getReplicationInfo();\n""if( result.errmsg ) {\n""print(tojson(result));\n""return;}\n""print(\"configured oplog size:   \" + result.logSizeMB + \"MB\");\n""print(\"log length start to end: \" + result.timeDiff + \"secs (\" + result.timeDiffHours + \"hrs)\");\n""print(\"oplog first event time:  \" + result.tFirst);\n""print(\"oplog last event time:   \" + result.tLast);\n""print(\"now:                     \" + result.now);}\n""DB.prototype.printSlaveReplicationInfo = function() {\n""function g(x) {\n""print(\"source:   \" + x.host);\n""var st = new Date( DB.tsToSeconds( x.syncedTo ) * 1000 );\n""var now = new Date();\n""print(\"syncedTo: \" + st.toString() );\n""var ago = (now-st)/1000;\n""var hrs = Math.round(ago/36)/100;\n""print(\"          = \" + Math.round(ago) + \"secs ago (\" + hrs + \"hrs)\");}\n""var L = this.getSisterDB(\"local\");\n""if( L.sources.count() == 0 ) {\n""print(\"local.sources is empty; is this db a --slave?\");\n""return;}\n""L.sources.find().forEach(g);}\n""DB.prototype.serverBuildInfo = function(){\n""return this._adminCommand( \"buildinfo\" );}\n""DB.prototype.serverStatus = function(){\n""return this._adminCommand( \"serverStatus\" );}\n""DB.prototype.version = function(){\n""return this.serverBuildInfo().version;}\n""DB.prototype.printShardingStatus = function(){\n""printShardingStatus( this.getSisterDB( \"config\" ) );}\n""if ( typeof Mongo == \"undefined\" ){\n""Mongo = function( host ){\n""this.init( host );}}\n""if ( ! Mongo.prototype ){\n""throw \"Mongo.prototype not defined\";}\n""if ( ! Mongo.prototype.find )\n""Mongo.prototype.find = function( ns , query , fields , limit , skip ){ throw \"find not implemented\"; }\n""if ( ! Mongo.prototype.insert )\n""Mongo.prototype.insert = function( ns , obj ){ throw \"insert not implemented\"; }\n""if ( ! Mongo.prototype.remove )\n""Mongo.prototype.remove = function( ns , pattern ){ throw \"remove not implemented;\" }\n""if ( ! Mongo.prototype.update )\n""Mongo.prototype.update = function( ns , query , obj , upsert ){ throw \"update not implemented;\" }\n""if ( typeof mongoInject == \"function\" ){\n""mongoInject( Mongo.prototype );}\n""Mongo.prototype.setSlaveOk = function() {\n""this.slaveOk = true;}\n""Mongo.prototype.getDB = function( name ){\n""return new DB( this , name );}\n""Mongo.prototype.getDBs = function(){\n""var res = this.getDB( \"admin\" ).runCommand( { \"listDatabases\" : 1 } );\n""assert( res.ok == 1 , \"listDatabases failed:\" + tojson( res ) );\n""return res;}\n""Mongo.prototype.getDBNames = function(){\n""return this.getDBs().databases.map(\n""function(z){\n""return z.name;}\n"");}\n""Mongo.prototype.getCollection = function(ns){\n""var idx = ns.indexOf( \".\" );\n""if ( idx < 0 )\n""throw \"need . in ns\";\n""var db = ns.substring( 0 , idx );\n""var c = ns.substring( idx + 1 );\n""return this.getDB( db ).getCollection( c );}\n""Mongo.prototype.toString = function(){\n""return \"mongo connection to \" + this.host;}\n""connect = function( url , user , pass ){\n""chatty( \"connecting to: \" + url )\n""if ( user && ! pass )\n""throw \"you specified a user and not a password.  either you need a password, or you're using the old connect api\";\n""var idx = url.indexOf( \"/\" );\n""var db;\n""if ( idx < 0 )\n""db = new Mongo().getDB( url );\n""else\n""db = new Mongo( url.substring( 0 , idx ) ).getDB( url.substring( idx + 1 ) );\n""if ( user && pass ){\n""if ( ! db.auth( user , pass ) ){\n""throw \"couldn't login\";}}\n""return db;}\n""MR = {};\n""MR.init = function(){\n""$max = 0;\n""$arr = [];\n""emit = MR.emit;\n""$numEmits = 0;\n""$numReduces = 0;\n""$numReducesToDB = 0;\n""gc();}\n""MR.cleanup = function(){\n""MR.init();\n""gc();}\n""MR.emit = function(k,v){\n""$numEmits++;\n""var num = nativeHelper.apply( get_num_ , [ k ] );\n""var data = $arr[num];\n""if ( ! data ){\n""data = { key : k , values : new Array(1000) , count : 0 };\n""$arr[num] = data;}\n""data.values[data.count++] = v;\n""$max = Math.max( $max , data.count );}\n""MR.doReduce = function( useDB ){\n""$numReduces++;\n""if ( useDB )\n""$numReducesToDB++;\n""$max = 0;\n""for ( var i=0; i<$arr.length; i++){\n""var data = $arr[i];\n""if ( ! data )\n""continue;\n""if ( useDB ){\n""var x = tempcoll.findOne( { _id : data.key } );\n""if ( x ){\n""data.values[data.count++] = x.value;}}\n""var r = $reduce( data.key , data.values.slice( 0 , data.count ) );\n""if ( r && r.length && r[0] ){\n""data.values = r;\n""data.count = r.length;}\n""else{\n""data.values[0] = r;\n""data.count = 1;}\n""$max = Math.max( $max , data.count );\n""if ( useDB ){\n""if ( data.count == 1 ){\n""tempcoll.save( { _id : data.key , value : data.values[0] } );}\n""else {\n""tempcoll.save( { _id : data.key , value : data.values.slice( 0 , data.count ) } );}}}}\n""MR.check = function(){\n""if ( $max < 2000 && $arr.length < 1000 ){\n""return 0;}\n""MR.doReduce();\n""if ( $max < 2000 && $arr.length < 1000 ){\n""return 1;}\n""MR.doReduce( true );\n""$arr = [];\n""$max = 0;\n""reset_num();\n""gc();\n""return 2;}\n""MR.finalize = function(){\n""tempcoll.find().forEach(\n""function(z){\n""z.value = $finalize( z._id , z.value );\n""tempcoll.save( z );}\n"");}\n""if ( typeof DBQuery == \"undefined\" ){\n""DBQuery = function( mongo , db , collection , ns , query , fields , limit , skip , batchSize ){\n""this._mongo = mongo;\n""this._db = db;\n""this._collection = collection;\n""this._ns = ns;\n""this._query = query || {};\n""this._fields = fields;\n""this._limit = limit || 0;\n""this._skip = skip || 0;\n""this._batchSize = batchSize || 0;\n""this._cursor = null;\n""this._numReturned = 0;\n""this._special = false;}\n""print( \"DBQuery probably won't have array access \" );}\n""DBQuery.prototype.help = function(){\n""print( \"DBQuery help\" );\n""print( \"\\t.sort( {...} )\" )\n""print( \"\\t.limit( n )\" )\n""print( \"\\t.skip( n )\" )\n""print( \"\\t.count() - total # of objects matching query, ignores skip,limit\" )\n""print( \"\\t.size() - total # of objects cursor would return skip,limit effect this\" )\n""print( \"\\t.explain()\" )\n""print( \"\\t.forEach( func )\" )\n""print( \"\\t.map( func )\" )}\n""DBQuery.prototype.clone = function(){\n""var q =  new DBQuery( this._mongo , this._db , this._collection , this._ns ,\n""this._query , this._fields ,\n""this._limit , this._skip , this._batchSize );\n""q._special = this._special;\n""return q;}\n""DBQuery.prototype._ensureSpecial = function(){\n""if ( this._special )\n""return;\n""var n = { query : this._query };\n""this._query = n;\n""this._special = true;}\n""DBQuery.prototype._checkModify = function(){\n""if ( this._cursor )\n""throw \"query already executed\";}\n""DBQuery.prototype._exec = function(){\n""if ( ! this._cursor ){\n""assert.eq( 0 , this._numReturned );\n""this._cursor = this._mongo.find( this._ns , this._query , this._fields , this._limit , this._skip , this._batchSize );\n""this._cursorSeen = 0;}\n""return this._cursor;}\n""DBQuery.prototype.limit = function( limit ){\n""this._checkModify();\n""this._limit = limit;\n""return this;}\n""DBQuery.prototype.batchSize = function( batchSize ){\n""this._checkModify();\n""this._batchSize = batchSize;\n""return this;}\n""DBQuery.prototype.skip = function( skip ){\n""this._checkModify();\n""this._skip = skip;\n""return this;}\n""DBQuery.prototype.hasNext = function(){\n""this._exec();\n""if ( this._limit > 0 && this._cursorSeen >= this._limit )\n""return false;\n""var o = this._cursor.hasNext();\n""return o;}\n""DBQuery.prototype.next = function(){\n""this._exec();\n""var o = this._cursor.hasNext();\n""if ( o )\n""this._cursorSeen++;\n""else\n""throw \"error hasNext: \" + o;\n""var ret = this._cursor.next();\n""if ( ret.$err && this._numReturned == 0 && ! this.hasNext() )\n""throw \"error: \" + tojson( ret );\n""this._numReturned++;\n""return ret;}\n""DBQuery.prototype.toArray = function(){\n""if ( this._arr )\n""return this._arr;\n""var a = [];\n""while ( this.hasNext() )\n""a.push( this.next() );\n""this._arr = a;\n""return a;}\n""DBQuery.prototype.count = function( applySkipLimit ){\n""var cmd = { count: this._collection.getName() };\n""if ( this._query ){\n""if ( this._special )\n""cmd.query = this._query.query;\n""else\n""cmd.query = this._query;}\n""cmd.fields = this._fields || {};\n""if ( applySkipLimit ){\n""if ( this._limit )\n""cmd.limit = this._limit;\n""if ( this._skip )\n""cmd.skip = this._skip;}\n""var res = this._db.runCommand( cmd );\n""if( res && res.n != null ) return res.n;\n""throw \"count failed: \" + tojson( res );}\n""DBQuery.prototype.size = function(){\n""return this.count( true );}\n""DBQuery.prototype.countReturn = function(){\n""var c = this.count();\n""if ( this._skip )\n""c = c - this._skip;\n""if ( this._limit > 0 && this._limit < c )\n""return this._limit;\n""return c;}\n""\n""DBQuery.prototype.itcount = function(){\n""var num = 0;\n""while ( this.hasNext() ){\n""num++;\n""this.next();}\n""return num;}\n""DBQuery.prototype.length = function(){\n""return this.toArray().length;}\n""DBQuery.prototype._addSpecial = function( name , value ){\n""this._ensureSpecial();\n""this._query[name] = value;\n""return this;}\n""DBQuery.prototype.sort = function( sortBy ){\n""return this._addSpecial( \"orderby\" , sortBy );}\n""DBQuery.prototype.hint = function( hint ){\n""return this._addSpecial( \"$hint\" , hint );}\n""DBQuery.prototype.min = function( min ) {\n""return this._addSpecial( \"$min\" , min );}\n""DBQuery.prototype.max = function( max ) {\n""return this._addSpecial( \"$max\" , max );}\n""DBQuery.prototype.forEach = function( func ){\n""while ( this.hasNext() )\n""func( this.next() );}\n""DBQuery.prototype.map = function( func ){\n""var a = [];\n""while ( this.hasNext() )\n""a.push( func( this.next() ) );\n""return a;}\n""DBQuery.prototype.arrayAccess = function( idx ){\n""return this.toArray()[idx];}\n""DBQuery.prototype.explain = function(){\n""var n = this.clone();\n""n._ensureSpecial();\n""n._query.$explain = true;\n""n._limit = n._limit * -1;\n""return n.next();}\n""DBQuery.prototype.snapshot = function(){\n""this._ensureSpecial();\n""this._query.$snapshot = true;\n""return this;}\n""DBQuery.prototype.shellPrint = function(){\n""try {\n""var n = 0;\n""while ( this.hasNext() && n < 20 ){\n""var s = tojson( this.next() , \"\" , true );\n""print( s );\n""n++;}\n""if ( this.hasNext() ){\n""print( \"has more\" );\n""___it___  = this;}\n""else {\n""___it___  = null;}}\n""catch ( e ){\n""print( e );}}\n""DBQuery.prototype.toString = function(){\n""return \"DBQuery: \" + this._ns + \" -> \" + tojson( this.query );}\n""if ( ( typeof  DBCollection ) == \"undefined\" ){\n""DBCollection = function( mongo , db , shortName , fullName ){\n""this._mongo = mongo;\n""this._db = db;\n""this._shortName = shortName;\n""this._fullName = fullName;\n""this.verify();}}\n""DBCollection.prototype.verify = function(){\n""assert( this._fullName , \"no fullName\" );\n""assert( this._shortName , \"no shortName\" );\n""assert( this._db , \"no db\" );\n""assert.eq( this._fullName , this._db._name + \".\" + this._shortName , \"name mismatch\" );\n""assert( this._mongo , \"no mongo in DBCollection\" );}\n""DBCollection.prototype.getName = function(){\n""return this._shortName;}\n""DBCollection.prototype.help = function() {\n""print(\"DBCollection help\");\n""print(\"\\tdb.foo.count()\");\n""print(\"\\tdb.foo.dataSize()\");\n""print(\"\\tdb.foo.distinct( key ) - eg. db.foo.distinct( 'x' )\");\n""print(\"\\tdb.foo.drop() drop the collection\");\n""print(\"\\tdb.foo.dropIndex(name)\");\n""print(\"\\tdb.foo.dropIndexes()\");\n""print(\"\\tdb.foo.ensureIndex(keypattern,options) - options should be an object with these possible fields: name, unique, dropDups\");\n""print(\"\\tdb.foo.reIndex()\");\n""print(\"\\tdb.foo.find( [query] , [fields]) - first parameter is an optional query filter. second parameter is optional set of fields to return.\");\n""print(\"\\t                                   e.g. db.foo.find( { x : 77 } , { name : 1 , x : 1 } )\");\n""print(\"\\tdb.foo.find(...).count()\");\n""print(\"\\tdb.foo.find(...).limit(n)\");\n""print(\"\\tdb.foo.find(...).skip(n)\");\n""print(\"\\tdb.foo.find(...).sort(...)\");\n""print(\"\\tdb.foo.findOne([query])\");\n""print(\"\\tdb.foo.findAndModify( { update : ... , remove : bool [, query: {}, sort: {}, 'new': false] } )\");\n""print(\"\\tdb.foo.getDB() get DB object associated with collection\");\n""print(\"\\tdb.foo.getIndexes()\");\n""print(\"\\tdb.foo.group( { key : ..., initial: ..., reduce : ...[, cond: ...] } )\");\n""print(\"\\tdb.foo.mapReduce( mapFunction , reduceFunction , <optional params> )\");\n""print(\"\\tdb.foo.remove(query)\");\n""print(\"\\tdb.foo.renameCollection( newName , <dropTarget> ) renames the collection.\");\n""print(\"\\tdb.foo.runCommand( name , <options> ) runs a db command with the given name where the 1st param is the colleciton name\" );\n""print(\"\\tdb.foo.save(obj)\");\n""print(\"\\tdb.foo.stats()\");\n""print(\"\\tdb.foo.storageSize() - includes free space allocated to this collection\");\n""print(\"\\tdb.foo.totalIndexSize() - size in bytes of all the indexes\");\n""print(\"\\tdb.foo.totalSize() - storage allocated for all data and indexes\");\n""print(\"\\tdb.foo.update(query, object[, upsert_bool, multi_bool])\");\n""print(\"\\tdb.foo.validate() - SLOW\");\n""print(\"\\tdb.foo.getShardVersion() - only for use with sharding\");}\n""DBCollection.prototype.getFullName = function(){\n""return this._fullName;}\n""DBCollection.prototype.getDB = function(){\n""return this._db;}\n""DBCollection.prototype._dbCommand = function( cmd , params ){\n""if ( typeof( cmd ) == \"object\" )\n""return this._db._dbCommand( cmd );\n""var c = {};\n""c[cmd] = this.getName();\n""if ( params )\n""Object.extend( c , params );\n""return this._db._dbCommand( c );}\n""DBCollection.prototype.runCommand = DBCollection.prototype._dbCommand;\n""DBCollection.prototype._massageObject = function( q ){\n""if ( ! q )\n""return {};\n""var type = typeof q;\n""if ( type == \"function\" )\n""return { $where : q };\n""if ( q.isObjectId )\n""return { _id : q };\n""if ( type == \"object\" )\n""return q;\n""if ( type == \"string\" ){\n""if ( q.length == 24 )\n""return { _id : q };\n""return { $where : q };}\n""throw \"don't know how to massage : \" + type;}\n""DBCollection.prototype._validateObject = function( o ){\n""if ( o._ensureSpecial && o._checkModify )\n""throw \"can't save a DBQuery object\";}\n""DBCollection._allowedFields = { $id : 1 , $ref : 1 };\n""DBCollection.prototype._validateForStorage = function( o ){\n""this._validateObject( o );\n""for ( var k in o ){\n""if ( k.indexOf( \".\" ) >= 0 ) {\n""throw \"can't have . in field names [\" + k + \"]\" ;}\n""if ( k.indexOf( \"$\" ) == 0 && ! DBCollection._allowedFields[k] ) {\n""throw \"field names cannot start with $ [\" + k + \"]\";}\n""if ( o[k] !== null && typeof( o[k] ) === \"object\" ) {\n""this._validateForStorage( o[k] );}}\n""};\n""DBCollection.prototype.find = function( query , fields , limit , skip ){\n""return new DBQuery( this._mongo , this._db , this ,\n""this._fullName , this._massageObject( query ) , fields , limit , skip );}\n""DBCollection.prototype.findOne = function( query , fields ){\n""var cursor = this._mongo.find( this._fullName , this._massageObject( query ) || {} , fields , -1 , 0 , 0 );\n""if ( ! cursor.hasNext() )\n""return null;\n""var ret = cursor.next();\n""if ( cursor.hasNext() ) throw \"findOne has more than 1 result!\";\n""if ( ret.$err )\n""throw \"error \" + tojson( ret );\n""return ret;}\n""DBCollection.prototype.insert = function( obj , _allow_dot ){\n""if ( ! obj )\n""throw \"no object passed to insert!\";\n""if ( ! _allow_dot ) {\n""this._validateForStorage( obj );}\n""if ( typeof( obj._id ) == \"undefined\" ){\n""var tmp = obj;\n""obj = {_id: new ObjectId()};\n""for (var key in tmp){\n""obj[key] = tmp[key];}}\n""this._mongo.insert( this._fullName , obj );\n""return obj._id;}\n""DBCollection.prototype.remove = function( t ){\n""this._mongo.remove( this._fullName , this._massageObject( t ) );}\n""DBCollection.prototype.update = function( query , obj , upsert , multi ){\n""assert( query , \"need a query\" );\n""assert( obj , \"need an object\" );\n""this._validateObject( obj );\n""this._mongo.update( this._fullName , query , obj , upsert ? true : false , multi ? true : false );}\n""DBCollection.prototype.save = function( obj ){\n""if ( obj == null || typeof( obj ) == \"undefined\" )\n""throw \"can't save a null\";\n""if ( typeof( obj._id ) == \"undefined\" ){\n""obj._id = new ObjectId();\n""return this.insert( obj );}\n""else {\n""return this.update( { _id : obj._id } , obj , true );}}\n""DBCollection.prototype._genIndexName = function( keys ){\n""var name = \"\";\n""for ( var k in keys ){\n""var v = keys[k];\n""if ( typeof v == \"function\" )\n""continue;\n""if ( name.length > 0 )\n""name += \"_\";\n""name += k + \"_\";\n""if ( typeof v == \"number\" )\n""name += v;}\n""return name;}\n""DBCollection.prototype._indexSpec = function( keys, options ) {\n""var ret = { ns : this._fullName , key : keys , name : this._genIndexName( keys ) };\n""if ( ! options ){}\n""else if ( typeof ( options ) == \"string\" )\n""ret.name = options;\n""else if ( typeof ( options ) == \"boolean\" )\n""ret.unique = true;\n""else if ( typeof ( options ) == \"object\" ){\n""if ( options.length ){\n""var nb = 0;\n""for ( var i=0; i<options.length; i++ ){\n""if ( typeof ( options[i] ) == \"string\" )\n""ret.name = options[i];\n""else if ( typeof( options[i] ) == \"boolean\" ){\n""if ( options[i] ){\n""if ( nb == 0 )\n""ret.unique = true;\n""if ( nb == 1 )\n""ret.dropDups = true;}\n""nb++;}}}\n""else {\n""Object.extend( ret , options );}}\n""else {\n""throw \"can't handle: \" + typeof( options );}\n""/*\n""return ret;\n""var name;\n""var nTrue = 0;\n""if ( ! isObject( options ) ) {\n""options = [ options ];}\n""if ( options.length ){\n""for( var i = 0; i < options.length; ++i ) {\n""var o = options[ i ];\n""if ( isString( o ) ) {\n""ret.name = o;\n""} else if ( typeof( o ) == \"boolean\" ) {\n""if ( o ) {\n""++nTrue;}}}\n""if ( nTrue > 0 ) {\n""ret.unique = true;}\n""if ( nTrue > 1 ) {\n""ret.dropDups = true;}}\n""*/\n""return ret;}\n""DBCollection.prototype.createIndex = function( keys , options ){\n""var o = this._indexSpec( keys, options );\n""this._db.getCollection( \"system.indexes\" ).insert( o , true );}\n""DBCollection.prototype.ensureIndex = function( keys , options ){\n""var name = this._indexSpec( keys, options ).name;\n""this._indexCache = this._indexCache || {};\n""if ( this._indexCache[ name ] ){\n""return;}\n""this.createIndex( keys , options );\n""if ( this.getDB().getLastError() == \"\" ) {\n""this._indexCache[name] = true;}}\n""DBCollection.prototype.resetIndexCache = function(){\n""this._indexCache = {};}\n""DBCollection.prototype.reIndex = function() {\n""return this._db.runCommand({ reIndex: this.getName() });}\n""DBCollection.prototype.dropIndexes = function(){\n""this.resetIndexCache();\n""var res = this._db.runCommand( { deleteIndexes: this.getName(), index: \"*\" } );\n""assert( res , \"no result from dropIndex result\" );\n""if ( res.ok )\n""return res;\n""if ( res.errmsg.match( /not found/ ) )\n""return res;\n""throw \"error dropping indexes : \" + tojson( res );}\n""DBCollection.prototype.drop = function(){\n""this.resetIndexCache();\n""var ret = this._db.runCommand( { drop: this.getName() } );\n""if ( ! ret.ok ){\n""if ( ret.errmsg == \"ns not found\" )\n""return false;\n""throw \"drop failed: \" + tojson( ret );}\n""return true;}\n""DBCollection.prototype.findAndModify = function(args){\n""var cmd = { findandmodify: this.getName() };\n""for (var key in args){\n""cmd[key] = args[key];}\n""var ret = this._db.runCommand( cmd );\n""if ( ! ret.ok ){\n""if (ret.errmsg == \"No matching object found\"){\n""return {};}\n""throw \"findAndModifyFailed failed: \" + tojson( ret.errmsg );}\n""return ret.value;}\n""DBCollection.prototype.renameCollection = function( newName , dropTarget ){\n""return this._db._adminCommand( { renameCollection : this._fullName ,\n""to : this._db._name + \".\" + newName ,\n""dropTarget : dropTarget } )}\n""DBCollection.prototype.validate = function() {\n""var res = this._db.runCommand( { validate: this.getName() } );\n""res.valid = false;\n""if ( res.result ){\n""var str = \"-\" + tojson( res.result );\n""res.valid = ! ( str.match( /exception/ ) || str.match( /corrupt/ ) );\n""var p = /lastExtentSize:(\\d+)/;\n""var r = p.exec( str );\n""if ( r ){\n""res.lastExtentSize = Number( r[1] );}}\n""return res;}\n""DBCollection.prototype.getShardVersion = function(){\n""return this._db._adminCommand( { getShardVersion : this._fullName } );}\n""DBCollection.prototype.getIndexes = function(){\n""return this.getDB().getCollection( \"system.indexes\" ).find( { ns : this.getFullName() } ).toArray();}\n""DBCollection.prototype.getIndices = DBCollection.prototype.getIndexes;\n""DBCollection.prototype.getIndexSpecs = DBCollection.prototype.getIndexes;\n""DBCollection.prototype.getIndexKeys = function(){\n""return this.getIndexes().map(\n""function(i){\n""return i.key;}\n"");}\n""DBCollection.prototype.count = function( x ){\n""return this.find( x ).count();}\n""\n""DBCollection.prototype.clean = function() {\n""return this._dbCommand( { clean: this.getName() } );}\n""\n""DBCollection.prototype.dropIndex =  function(index) {\n""assert(index , \"need to specify index to dropIndex\" );\n""if ( ! isString( index ) && isObject( index ) )\n""index = this._genIndexName( index );\n""var res = this._dbCommand( \"deleteIndexes\" ,{ index: index } );\n""this.resetIndexCache();\n""return res;}\n""DBCollection.prototype.copyTo = function( newName ){\n""return this.getDB().eval(\n""function( collName , newName ){\n""var from = db[collName];\n""var to = db[newName];\n""to.ensureIndex( { _id : 1 } );\n""var count = 0;\n""var cursor = from.find();\n""while ( cursor.hasNext() ){\n""var o = cursor.next();\n""count++;\n""to.save( o );}\n""return count;\n""} , this.getName() , newName\n"");}\n""DBCollection.prototype.getCollection = function( subName ){\n""return this._db.getCollection( this._shortName + \".\" + subName );}\n""DBCollection.prototype.stats = function( scale ){\n""return this._db.runCommand( { collstats : this._shortName , scale : scale } );}\n""DBCollection.prototype.dataSize = function(){\n""return this.stats().size;}\n""DBCollection.prototype.storageSize = function(){\n""return this.stats().storageSize;}\n""DBCollection.prototype.totalIndexSize = function( verbose ){\n""var stats = this.stats();\n""if (verbose){\n""for (var ns in stats.indexSizes){\n""print( ns + \"\\t\" + stats.indexSizes[ns] );}}\n""return stats.totalIndexSize;}\n""DBCollection.prototype.totalSize = function(){\n""var total = this.storageSize();\n""var mydb = this._db;\n""var shortName = this._shortName;\n""this.getIndexes().forEach(\n""function( spec ){\n""var coll = mydb.getCollection( shortName + \".$\" + spec.name );\n""var mysize = coll.storageSize();\n""total += coll.dataSize();}\n"");\n""return total;}\n""DBCollection.prototype.convertToCapped = function( bytes ){\n""if ( ! bytes )\n""throw \"have to specify # of bytes\";\n""return this._dbCommand( { convertToCapped : this._shortName , size : bytes } )}\n""DBCollection.prototype.exists = function(){\n""return this._db.system.namespaces.findOne( { name : this._fullName } );}\n""DBCollection.prototype.isCapped = function(){\n""var e = this.exists();\n""return ( e && e.options && e.options.capped ) ? true : false;}\n""DBCollection.prototype.distinct = function( keyString , query ){\n""var res = this._dbCommand( { distinct : this._shortName , key : keyString , query : query || {} } );\n""if ( ! res.ok )\n""throw \"distinct failed: \" + tojson( res );\n""return res.values;}\n""DBCollection.prototype.group = function( params ){\n""params.ns = this._shortName;\n""return this._db.group( params );}\n""DBCollection.prototype.groupcmd = function( params ){\n""params.ns = this._shortName;\n""return this._db.groupcmd( params );}\n""MapReduceResult = function( db , o ){\n""Object.extend( this , o );\n""this._o = o;\n""this._keys = Object.keySet( o );\n""this._db = db;\n""this._coll = this._db.getCollection( this.result );}\n""MapReduceResult.prototype._simpleKeys = function(){\n""return this._o;}\n""MapReduceResult.prototype.find = function(){\n""return DBCollection.prototype.find.apply( this._coll , arguments );}\n""MapReduceResult.prototype.drop = function(){\n""return this._coll.drop();}\n""\n""MapReduceResult.prototype.convertToSingleObject = function(){\n""var z = {};\n""this._coll.find().forEach( function(a){ z[a._id] = a.value; } );\n""return z;}\n""\n""DBCollection.prototype.mapReduce = function( map , reduce , optional ){\n""var c = { mapreduce : this._shortName , map : map , reduce : reduce };\n""if ( optional )\n""Object.extend( c , optional );\n""var raw = this._db.runCommand( c );\n""if ( ! raw.ok )\n""throw \"map reduce failed: \" + tojson( raw );\n""return new MapReduceResult( this._db , raw );}\n""DBCollection.prototype.toString = function(){\n""return this.getFullName();}\n""DBCollection.prototype.toString = function(){\n""return this.getFullName();}\n""DBCollection.prototype.tojson = DBCollection.prototype.toString;\n""DBCollection.prototype.shellPrint = DBCollection.prototype.toString;\n" ;

比如我们知道可以从db shell中查看当前操作,但是不知道怎么在客户端中实现这个功能,可以找到这个文件中的:

"DB.prototype.currentOp = function(){\n"
"return db.$cmd.sys.inprog.findOne();}\n"
"DB.prototype.currentOP = DB.prototype.currentOp;\n"
"DB.prototype.killOp = function(op) {\n"
"if( !op )\n"
"throw \"no opNum to kill specified\";\n"
"return db.$cmd.sys.killop.findOne({'op':op});}\n"
"DB.prototype.killOP = DB.prototype.killOp;\n"

这几句,我想大家就知道怎么实现了吧。

mongodb是一个好东西,即使和sql server 性能差不多也是好东西(何况性能这么好),因为免费/开源,sql server多贵啊。不过呢,使用nosql还是要看应用的,mongodb的数据基于bson,列名都是重复保存的,所以占用的空间比较大一点,不太适合列数很多的数据,如果要保存日志的话甚至可以除了需要索引的字段都以一个字符串来保存。

mongodb有关的研究相关推荐

  1. Redis和Mongodb应用场景研究

    现在的分布式项目基本都会用到redis和mongodb,可是redis和mongdb到底有什么不同呢,今天我就基于我们公司的项目来具体介绍一下redis和mongodb的各自的应用场景. 首先我们这个 ...

  2. Linux下MongoDB的安装,通过配置文件启动Mongodb的方式研究,mongodb自启动脚本(Linux),Windows下安装MongoDB服务,集群部署,数据导出和恢复

    关于MongoDB的windows的 安装,可以参考: http://www.runoob.com/mongodb/mongodb-window-install.html 关于Linux的安装可以参考 ...

  3. 【转】MongoDB资料汇总专题

    1.MongoDB是什么 MongoDB介绍PPT分享 MongoDB GridFS介绍PPT两则 初识 MongoDB GridFS MongoDB GridFS 介绍 一个NoSQL与MongoD ...

  4. MongoDB学习指导

    原文地址:http://blog.csdn.net/jakenson/article/details/7060431 MongoDB的内部构造<MongoDB The Definitive Gu ...

  5. 关于Mongodb的全面总结

    MongoDB的内部构造<MongoDB The Definitive Guide> MongoDB的官方文档基本是how to do的介绍,而关于how it worked却少之又少,本 ...

  6. 关于Mongodb的全面总结,学习mongodb的人,可以从这里开始!

    转载地址:http://blog.csdn.net/he90227/article/details/45674513 原文地址:http://blog.csdn.NET/jakenson/articl ...

  7. MongoDB 全面总结

    原文地址:http://blog.csdn.net/jakenson/article/details/7060431 MongoDB的内部构造<MongoDB The Definitive Gu ...

  8. MongoDB全面总结

    原文地址:http://blog.csdn.net/jakenson/article/details/7060431 MongoDB的内部构造<MongoDB The Definitive Gu ...

  9. Mongodb从这里开始

    原文地址:http://blog.csdn.net/jakenson/article/details/7060431 MongoDB的内部构造<MongoDB The Definitive Gu ...

最新文章

  1. gridview里找到控件
  2. Python中for else注意事项
  3. python raw_input为什么不能用_热门问题 | 为什么发票不能用订书器只能用胶水?...
  4. HDU Redraw Beautiful Drawings 推断最大流是否唯一解
  5. oracle插入回车换行符
  6. 多线程----join插队
  7. 【LeetCode】3月27日打卡-Day12
  8. ActiveRecord教程
  9. Bootstrap导航条中组件的排列
  10. ElasticSearch概述及安装
  11. 使用IE建多个会话的小技巧
  12. JSK-4 简单斐波那契【基础+打表+记忆化递归】
  13. win10无法访问服务器上的共享文件夹怎么设置,提示:你不能访问此共享文件夹,因为你组织的安全策略阻止未经身份验证的来宾访问...
  14. 使用免费的Open NFC simulator模拟器在BlackBerry模拟器上进行NFC程序调试
  15. 工作站安装Ubuntu,显卡驱动,pytorch全流程
  16. PDF怎么转换成CAD图纸?两个方法轻松操作。
  17. arduino教程汇总
  18. 最新大麦网抢票脚本-Python实战
  19. 小学生学计算机图片大全集,小学生电脑绘画作品欣赏
  20. Jenkins 如何与 Kubernetes 集群的 Tekton Pipeline 交互?

热门文章

  1. reactrouter监听路由变化_前端路由三种模式
  2. WebPack配置文件抽离存放
  3. python代码混淆工具_有没有好的 python 混淆器 推荐一个
  4. gradle配置到阿里云_通过图文步骤的方式,带你配置阿里云服务器搭建网站
  5. Android Studio的TableLayout的使用(自定义列拉伸,收缩,隐藏,横跨列)
  6. 20190821:(leetcode习题)验证回文字符串
  7. linux c语言 udp 接收和发送数据用同一个端口_【Python学习笔记】80、UDP编程
  8. 点击查询后在表格中获取控件的值
  9. kafka内部消费偏移
  10. 清华排名首登亚洲第一,今年财务预算300亿