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?

  這里我們進入mongo.exe,通過方法的源碼來看看(js中所有的方法不加小括號時都可以直接打印出該方法的代碼)

> db.runCommand
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 );
}

   runComman的底層使用findOne,很完美的主從調用關系,符合了我們的代碼分層審美。

二、命令&方法,蛋和雞

  接下來我們來看一個異類: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 shell的對應關系

  四:mongo中的游標與數據一致性的取舍

   


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM