Thinkphp使用mongodb数据库实现多条件查询方法


Posted in PHP onJune 26, 2014

有个项目用了mongodb数据库,查询条件有and也有or,按Thinkphp官方手册,使用复合查询(_complex),getLastSql输出查询语句,发现查询条件是空的.用字符串模式查询(_string),请求字符串查询(_query)无法满足需求.估计用mongodb的用户不多,thinkphp官方对这方面支持也不够.打开thinkphp的mongodb驱动,Thinkphp/Extend/Driver/Db/DbMongo.class.php,找到protected function parseThinkWhere($key,$val)方法,可以发现,switch里没有_complex,也就是说,Thinkphp使用mongodb时,根本不支持复合查询.加上:

case '_complex'://复合查询

             $arr   = array();

             foreach ($val as $nkey=>$nval){

              if( strpos($nkey,'_')!=0)

              {

               $parseArr=$this->parseWhereItem($nkey,$nval);

               //转换成对象

               $obj=new stdClass();

               foreach ($parseArr as $pkey=>$pval)

               {

                $obj->$pkey=$pval;

               }

               array_push($arr, $obj);

              }

             }

             if(isset($val['_logic']) && strtolower($val['_logic']) == 'or' ) {

              unset($val['_logic']);

              $query['$or']   =  $arr;

             }

             break;

这里之所以要转换成对象,是因为使用thinkphp使用json_encode函数生成查询语句,但是如果数组元素带key,json_encode函数会把数组转换成对象的形式,mongodb不能识别.因为目前只用到or,所以,代码只对or作了处理.
另外,发现个BUG(不知道算不算),在parseWhere方法中:

foreach ($where as $key=>$val){

            if('_id' != $key && 0===strpos($key,'_')) {

                // 解析特殊条件表达式

                //原 $query=$this->parseThinkWhere($key,$val);

                $query   = array_merge($query,$this->parseThinkWhere($key,$val));

            }else{

                // 查询字段的安全过滤

                if(!preg_match('/^[A-Z_\|\&\-.a-z0-9]+$/',trim($key))){

                    throw_exception(L('_ERROR_QUERY_').':'.$key);

                }

                $key = trim($key);

                if(strpos($key,'|')) {

                    $array   =  explode('|',$key);

                    $str   = array();

                    foreach ($array as $k){

                        $str[]   = $this->parseWhereItem($k,$val);

                    }

                    $query['$or'] =    $str;

                }elseif(strpos($key,'&')){

                    $array   =  explode('&',$key);

                    $str   = array();

                    foreach ($array as $k){

                        $str[]   = $this->parseWhereItem($k,$val);

                    }

                    $query   = array_merge($query,$str);

                }else{

                    $str   = $this->parseWhereItem($key,$val);

                    $query   = array_merge($query,$str);

                }

            }

        }

解析特殊条件表达式时,源代码里是$query=$this->parseThinkWhere($key,$val);当特殊表达式在where数组里不是第一个元素时,就出错了,else里的代码得到的$query数组,都没了.

PHP 相关文章推荐
基于Snoopy的PHP近似完美获取网站编码的代码
Oct 23 PHP
php开启与关闭错误提示适用于没有修改php.ini的权限
Oct 16 PHP
Codeigniter(CI)框架分页函数及相关知识
Nov 03 PHP
深入理解PHP中的Streams工具
Jul 03 PHP
php中二维数组排序问题方法详解
Aug 28 PHP
微信公众号开发之语音消息识别php代码
Aug 08 PHP
php封装的smartyBC类完整实例
Oct 19 PHP
PHP实现随机生成水印图片功能
Mar 22 PHP
php实现用户登陆简单实例
Apr 04 PHP
PHP 进度条函数的简单实例
Sep 19 PHP
PHP实现的字符串匹配算法示例【sunday算法】
Dec 19 PHP
PHP使用Redis长连接的方法详解
Feb 12 PHP
ThinkPHP页面跳转success与error方法概述
Jun 25 #PHP
修改ThinkPHP缓存为Memcache的方法
Jun 25 #PHP
ThinkPHP的截取字符串函数无法显示省略号的解决方法
Jun 25 #PHP
ThinkPHP多表联合查询的常用方法
Mar 24 #PHP
ThinkPHP2.0读取MSSQL提示Incorrect syntax near the keyword 'AS'的解决方法
Jun 25 #PHP
ThinkPHP查询中的魔术方法简述
Jun 25 #PHP
Thinkphp实现MySQL读写分离操作示例
Jun 25 #PHP
You might like
php使用正则表达式去掉html中的注释方法
2016/11/03 PHP
基于js disabled="false"不起作用的解决办法
2013/06/26 Javascript
jquery异步跨域访问代码
2013/06/28 Javascript
JavaScript利用正则表达式去除日期中的-
2014/06/09 Javascript
JavaScript简单实现鼠标移动切换图片的方法
2016/02/23 Javascript
jQuery ztree实现动态树形多选菜单
2016/08/12 Javascript
Vuex2.0+Vue2.0构建备忘录应用实践
2016/11/30 Javascript
jQuery绑定事件方法及区别(bind,click,on,live,one)
2017/08/14 jQuery
vue3.0 CLI - 2.2 - 组件 home.vue 的初步改造
2018/09/14 Javascript
React 父子组件通信的实现方法
2019/12/05 Javascript
js中Function引用类型常见有用的方法和属性详解
2019/12/11 Javascript
Vue解析剪切板图片并实现发送功能
2020/02/04 Javascript
VUE项目axios请求头更改Content-Type操作
2020/07/24 Javascript
关于angular引入ng-zorro的问题浅析
2020/09/09 Javascript
js节流防抖应用场景,以及在vue中节流防抖的具体实现操作
2020/09/21 Javascript
vuex刷新后数据丢失的解决方法
2020/10/18 Javascript
js实现网页随机验证码
2020/10/19 Javascript
[02:31]《DAC最前线》之选手酒店现场花絮
2015/01/30 DOTA
[37:37]DAC2018 4.4 淘汰赛 Optic vs Mineski 第二场
2018/04/05 DOTA
Python+Socket实现基于UDP协议的局域网广播功能示例
2017/08/31 Python
对pandas进行数据预处理的实例讲解
2018/04/20 Python
pandas DataFrame 根据多列的值做判断,生成新的列值实例
2018/05/18 Python
Python中return self的用法详解
2018/07/27 Python
教你利用Python玩转histogram直方图的五种方法
2018/07/30 Python
numpy ndarray 取出满足特定条件的某些行实例
2019/12/05 Python
Jupyter打开图形界面并画出正弦函数图像实例
2020/04/24 Python
python如何建立全零数组
2020/07/19 Python
详解python程序中的多任务
2020/09/16 Python
python利用opencv保存、播放视频
2020/11/02 Python
selenium3.0+python之环境搭建的方法步骤
2021/02/01 Python
玖熙女鞋美国官网:Nine West
2016/10/06 全球购物
怎样声明子类
2013/07/02 面试题
写演讲稿所需要注意的4个条件
2014/01/09 职场文书
超市店庆活动方案
2014/08/31 职场文书
2014年评职称工作总结
2014/11/20 职场文书
js基础语法与maven项目配置教程案例
2021/07/15 Javascript