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 相关文章推荐
一个用于网络的工具函数库
Oct 09 PHP
网站用php实现paypal整合方法
Nov 28 PHP
php去除重复字的实现代码
Sep 16 PHP
PHP数据集构建JSON格式及新数组的方法
Nov 07 PHP
thinkphp使用literal防止模板标签被解析的方法
Nov 22 PHP
php根据某字段对多维数组进行排序的方法
Mar 07 PHP
PHP结合Jquery和ajax实现瀑布流特效
Jan 07 PHP
WordPress的文章自动添加关键词及关键词的SEO优化
Mar 01 PHP
PHP实现webshell扫描文件木马的方法
Jul 31 PHP
PHP实现的mysql操作类【MySQL与MySQLi方式】
Oct 07 PHP
ThinkPHP3.2.3框架实现的空模块、空控制器、空操作,跳转到错误404页面图文详解
Apr 03 PHP
PHP创建XML接口示例
Jul 04 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 ? EasyUI DataGrid 资料存的方式介绍
2012/11/07 PHP
[原创]CI(CodeIgniter)简单统计访问人数实现方法
2016/01/19 PHP
PHP preg_match实现正则表达式匹配功能【输出是否匹配及匹配值】
2017/07/19 PHP
Laravel Eloquent分表方法并使用模型关联的实现
2019/11/25 PHP
javascript 常用关键字列表集合
2007/12/04 Javascript
下拉列表select 由左边框移动到右边示例
2013/12/04 Javascript
变量声明时命名与变量作为对象属性时命名的区别解析
2013/12/06 Javascript
jQuery的cookie插件实现保存用户登陆信息
2014/04/15 Javascript
巧用replace将文字表情替换为图片
2014/04/17 Javascript
jquery mobile 移动web(5)
2015/12/20 Javascript
javascript实现瀑布流加载图片原理
2016/02/02 Javascript
JS前向后瞻正则表达式定义与用法示例
2016/12/27 Javascript
使用bootstrap-paginator.js 分页来进行ajax 异步分页请求示例
2017/03/09 Javascript
jquery PrintArea 实现票据的套打功能(代码)
2017/03/17 Javascript
详解vue-cli脚手架中webpack配置方法
2018/08/22 Javascript
详解CommonJS和ES6模块循环加载处理的区别
2018/12/26 Javascript
解决cordova+vue 项目打包成APK应用遇到的问题
2019/05/10 Javascript
JS实现的排列组合算法示例
2019/07/16 Javascript
Vuex modules模式下mapState/mapMutations的操作实例
2019/10/17 Javascript
JavaScript修改注册表实例代码
2020/01/05 Javascript
vue各种事件监听实例(小结)
2020/06/24 Javascript
Element图表初始大小及窗口自适应实现
2020/07/10 Javascript
vue3.0搭配.net core实现文件上传组件
2020/10/29 Javascript
Python之Scrapy爬虫框架安装及简单使用详解
2017/12/22 Python
python3爬取淘宝信息代码分析
2018/02/10 Python
python 从文件夹抽取图片另存的方法
2018/12/04 Python
Python设计模式之组合模式原理与用法实例分析
2019/01/11 Python
Python GUI库PyQt5图形和特效样式QSS介绍
2020/02/25 Python
Python编程快速上手——strip()函数的正则表达式实现方法分析
2020/02/29 Python
Python QTimer实现多线程及QSS应用过程解析
2020/07/11 Python
CSS3实现10种Loading效果
2016/07/11 HTML / CSS
应届生幼儿园求职信
2013/11/12 职场文书
捐款感谢信
2015/01/20 职场文书
小米11和iphone12哪个值得买?小米11对比iphone12评测
2021/04/21 数码科技
分析MySQL抛出异常的几种常见解决方式
2021/05/18 MySQL
Springboot-cli 开发脚手架,权限认证,附demo演示
2022/04/28 Java/Android