mongodb源码分析(四)查询1之mongo的查询请求

本文深入探讨MongoDB的查询机制,从mongo客户端的查询请求开始,包括请求的封装成Message结构、发送到服务器及接收响应的过程。通过分析db.coll.find({x:1})的例子,阐述查询的具体流程。
摘要由CSDN通过智能技术生成

           在之前的2篇文章中分别分析了mongod和mongo的启动流程,下面开始将分析mongodb的查询,由于查询部分流程比较长,将分成mongo端的请求,mongod端的数据库的加载,mongod query的选取,mongod文档的匹配与数据的响应几部分来分析。

         首先进入mongo的查询请求部分.mongo的查询请求部分归纳起来很简单就是将请求分装成一个Message结构,然后将其发送到服务端,等待服务端的相应数据,取得数据最后显示结果.下面来看具体流程分析吧.

   当我们点击db.coll.find({x:1})时按照上一篇文章的讲解,我们首先来到了mongo/shell/dbshell.cpp

            if ( ! wascmd ) {
                try {
                    if ( scope->exec( code.c_str() , "(shell)" , false , true , false ) )//执行相应的javascript代码
                        scope->exec( "shellPrintHelper( __lastres__ );" , "(shell2)" , true , true , false );
                }
                catch ( std::exception& e ) {
                    cout << "error:" << e.what() << endl;
                }
            }
下面进入javascript代码,其在mongo/shell/collection.js.

	//这里因为我们只设置了query,所以其它选项都是空的,this.getQueryOptions()目前只有一个SlaveOK的option,在replset模式下是不能查询secondary服务器的,需要调用rs.SlaveOK()之后才能对secondary进行查询,其执行SlaveOK后每次查询时都会添加一个QueryOption.
DBCollection.prototype.find = function (query, fields, limit, skip, batchSize, options) {
    return new DBQuery( this._mongo , this._db , this ,
                        this._fullName , this._massageObject( query ) , fields , limit , skip , batchSize , options || this.getQueryOptions() );
}
继续前进看看DBQuery,上一篇文章提到这里的new DBQuery对象的创建发生在:

    JSBool dbquery_constructor( JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval ) {
        try {
            smuassert( cx ,  "DDQuery needs at least 4 args" , argc >= 4 );
	    //整个代码都是创建一个DBQuery对象,并未进行任何的查询请求动作
            Convertor c(cx);
            c.setProperty( obj , "_mongo" , argv[0] );
            c.setProperty( obj , "_db" , argv[1] );
            c.setProperty( obj , "_collection" , argv[2] );
            c.setProperty( obj , "_ns" , argv[3] );

            if ( argc > 4 && JSVAL_IS_OBJECT( argv[4] ) )
                c.setProperty( obj , "_query" , argv[4] );
            else {
                JSObject * temp = JS_NewObject( cx , 0 , 0 , 0 );
                CHECKNEWOBJECT( temp, cx, "dbquery_constructor" );
                c.setProperty( obj , "_query" , OBJECT_TO_JSVAL( temp ) );
            }

            if ( argc > 5 && JSVAL_IS_OBJECT( argv[5] ) )
                c.setProperty( obj , "_fields" , argv[5] );
            else
                c.setProperty( obj , "_fields" , JSVAL_NULL );


            if ( argc > 6 && JSVAL_IS_NUMBER( argv[6] ) )
                c.setProperty( obj , "_limit" , argv[6] );
            else
                c.setProperty( obj , "_limit" , JSVAL_ZERO );

            if ( argc > 7 && JSVAL_IS_NUMBER( argv[7] ) )
                c.setProperty( obj , "_skip" , argv[7] );
            else
                c.setProperty( obj , "_skip" , JSVAL_ZERO );

            if ( argc > 8 && JSVAL_IS_NUMBER( argv[8] ) )
                c.setProperty( obj , "_batchSize" , argv[8] );
            else
                c.setProperty( obj , "_batchSize" , JSVAL_ZERO );

            if ( argc > 9 && JSVAL_IS_NUMBER( argv[9] ) )
                c.setProperty( obj , "_options" , argv[9] );
            else
                c.setProperty( obj , "_options" , JSVAL_ZERO );

            c.
  • 0
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值