zoukankan      html  css  js  c++  java
  • 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中的游标与数据一致性的取舍

       

  • 相关阅读:
    360天擎安装上之后,手机开热点之后就没有办法连接
    Redis基本数据类型--Hash(哈希)
    Redis基本数据类型--Set
    redis的五种基本数据类型之List
    Redis的五种基本数据类型 String
    Android应用程序的安装位置
    Java中long和Long有什么区别(转)
    Logcat打印调试信息
    Java GUI图形界面开发工具
    CSDN精选Android开发博客
  • 原文地址:https://www.cnblogs.com/ttjsndx/p/9947892.html
Copyright © 2011-2022 走看看