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 相关文章推荐
php数组对百万数据进行排除重复数据的实现代码
Jun 08 PHP
PHP autoload与spl_autoload自动加载机制的深入理解
Jun 05 PHP
PHP添加Xdebug扩展的方法
Feb 12 PHP
PHP中使用sleep造成mysql读取失败的案例和解决方法
Aug 21 PHP
destoon实现不同会员组公司名称显示不同的颜色的方法
Aug 22 PHP
php与Mysql的一些简单的操作
Feb 26 PHP
laravel容器延迟加载以及auth扩展详解
Mar 02 PHP
php查看网页源代码的方法
Mar 13 PHP
PHP中创建和验证哈希的简单方法实探
Jul 06 PHP
详解WordPress中提醒安装插件以及隐藏插件的功能实现
Dec 25 PHP
PHP XML Expat解析器知识点总结
Feb 15 PHP
PHP读取目录树的实现方法分析
Mar 22 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
浅析application/x-www-form-urlencoded和multipart/form-data的区别
2014/06/22 PHP
php中各种定义变量的方法小结
2017/10/18 PHP
javaScript 利用闭包模拟对象的私有属性
2011/12/29 Javascript
Jquery实现带动画效果的经典二级导航菜单
2013/03/22 Javascript
jQuery学习笔记之jQuery.extend(),jQuery.fn.extend()分析
2014/06/09 Javascript
jQuery中 attr() 方法使用小结
2015/05/03 Javascript
clipboard.js无需Flash无需依赖任何JS库实现文本复制与剪切
2015/10/10 Javascript
Bootstrap每天必学之级联下拉菜单
2016/03/27 Javascript
基于JS实现导航条之调用网页助手小精灵的方法
2016/06/17 Javascript
如何防止INPUT按回车自动提交表单FORM
2016/12/06 Javascript
JavaScript实现替换字符串中最后一个字符的方法
2017/03/07 Javascript
js实现添加删除表格(两种方法)
2017/04/27 Javascript
通过示例彻底搞懂js闭包
2017/08/10 Javascript
vue 使用element-ui中的Notification自定义按钮并实现关闭功能及如何处理多个通知
2019/08/17 Javascript
vue自定义switch开关组件,实现样式可自行更改
2019/11/01 Javascript
解决vue的router组件component在import时不能使用变量问题
2020/07/26 Javascript
Vue 实现对quill-editor组件中的工具栏添加title
2020/08/03 Javascript
JavaScript 判断浏览器是否是IE
2021/02/19 Javascript
Python天气预报采集器实现代码(网页爬虫)
2012/10/07 Python
Python Socket实现简单TCP Server/client功能示例
2017/08/05 Python
如何高效使用Python字典的方法详解
2017/08/31 Python
Python正则表达式和元字符详解
2018/11/29 Python
利用python求积分的实例
2019/07/03 Python
django基础学习之send_mail功能
2019/08/07 Python
Python开发之基于模板匹配的信用卡数字识别功能
2020/01/13 Python
python3实现网页版raspberry pi(树莓派)小车控制
2020/02/12 Python
Python 调用有道翻译接口实现翻译
2020/03/02 Python
Electric官网:美国高级眼镜和配件品牌
2020/06/04 全球购物
政府绩效管理实施方案
2014/05/04 职场文书
信用社主任竞聘演讲稿
2014/05/23 职场文书
投标诚信承诺书
2014/05/26 职场文书
入党转正申请报告
2015/05/15 职场文书
老乡会致辞
2015/07/28 职场文书
小学体育队列队形教学反思
2016/02/16 职场文书
高考满分作文赏析(2篇)
2019/08/12 职场文书
聊聊Lombok中的@Builder注解使用教程
2021/11/17 Java/Android