mongo的runCommand與集合操作函數的關系
除了特殊註釋外,本文的測試結果均基於 spring-data-mongodb:1.10.6.RELEASE(spring-boot-starter:1.5.6.RELEASE),MongoDB 3.0.6
一:單純的主從關系
按照我們多年的mvc經驗,所有的方法的調用都應該遵循一個從上到下的關系,沒有遇到過dao層調service層的。
所以主觀上我們需要確認一個順序,是runCommand封裝了集合操作函數,還是集合操作函數封裝了runCommand?
這裏我們通過方法的源碼來看看(js中所有的方法不加小括號時都可以直接打印出該方法的代碼)
> db.runCommandfunction ( obj, extra ){ if ( typeof( obj ) == "string" ){ var n = {}; n[obj] = 1; obj = n; if ( extra && typeof( extra ) == "object" ) { for ( var x in extra ) { n[x] = extra[x]; } } } returnthis.getCollection( "$cmd" ).findOne( obj ); }
很完美的主從調用關系,符合了我們的審美。
二、命令&方法,蛋和雞
接下來我們來看一個異類:aggregate。
> db.user.aggregate function (pipeline, extraOpts) { if (!(pipeline instanceof Array)) { // support legacy varargs form. (Also handles db.foo.aggregate()) pipeline = argumentsToArray(arguments) extraOpts= {} } else if (extraOpts === undefined) { extraOpts = {}; } var cmd = {pipeline: pipeline}; Object.extend(cmd, extraOpts); if (!(‘cursor‘ in cmd)) { // implicitly use cursors cmd.cursor = {}; } var res = this.runCommand("aggregate", cmd); //...此處省去了一些無關代碼,可自行下載3.0.06版本的mongo查看 return res; }
這個runCommand不會就是那個runCommand吧?,讓我們將this替換為方法的調用對象db.user。(關於js中this指代的對象建議閱讀王福朋的深入理解javascript的原型和閉包)
> db.user.runCommand function ( cmd , params ){ if ( typeof( cmd ) == "object" ) return this._db._dbCommand( cmd ); var c = {}; c[cmd] = this.getName(); if ( params ) Object.extend( c , params ); return this._db._dbCommand( c ); }
讓我們再替換掉this,繼續往下看。
> db.user._db._dbCommand function ( obj, extra ){ if ( typeof( obj ) == "string" ){ var n = {}; n[obj] = 1; obj = n; if ( extra && typeof( extra ) == "object" ) { for ( var x in extra ) { n[x] = extra[x]; } } } return this.getCollection( "$cmd" ).findOne( obj ); }
db._collection_.aggregate()繞了一大圈,又回到了db.$cmd.findOne()。為什麽不讓aggregate直接調用findOne,再讓db.runCommand{{"aggregate":"_collection_","pipeline":[]}}調用db._collection_.aggregate?這種雞生蛋,蛋生雞的結構,後期又該如何快速的進行版本升級?這樣做的原因我們在第四章 MONGO中的特殊集合$CMD 中會講。現在我們先記住aggregate的這種調用模式,然後研究在spring-data-mongodb中,該從哪一層入手使用原生的aggregate查詢。
一:spring-data-mongodb 使用原生aggregate語句
二:mongo的runCommand與集合操作函數的關系
三:spring-data-mongodb底層與mongo-driver的交互
四:mongo中的特殊集合$cmd
mongo的runCommand與集合操作函數的關系