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 05 PHP
php开发环境配置记录
Jan 14 PHP
PHP中使用addslashes函数转义的安全性原理分析
Nov 03 PHP
浅谈PHP解析URL函数parse_url和parse_str
Nov 11 PHP
PHP的Yii框架中行为的定义与绑定方法讲解
Mar 18 PHP
php flush无效,IIS7下php实时输出的方法
Aug 25 PHP
php+mysql查询实现无限下级分类树输出示例
Oct 03 PHP
Laravel实现表单提交
May 07 PHP
详解php实现页面静态化原理
Jun 21 PHP
利用PHPStorm如何开发Laravel应用详解
Aug 30 PHP
php实现推荐功能的简单实例
Sep 29 PHP
调试php程序的简单步骤
Oct 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 上传功能实例代码
2010/04/13 PHP
PHP cookie与session会话基本用法实例分析
2019/11/18 PHP
JavaScript函数的4种调用方法详解
2014/04/22 Javascript
js重写alert控件(适合学习js的新手朋友)
2014/08/24 Javascript
JS简单实现城市二级联动选择插件的方法
2015/08/19 Javascript
解决JavaScript数字精度丢失问题的方法
2015/12/03 Javascript
jquery插件EasyUI中form表单提交实例分享
2016/01/11 Javascript
TypeScript Type Innference(类型判断)
2016/03/10 Javascript
JS原型链 详解及示例代码
2016/09/06 Javascript
原生js实现弹出层登录拖拽功能
2016/12/05 Javascript
详解微信小程序 页面跳转 传递参数
2016/12/08 Javascript
JavaScript无阻塞加载和defer、async详解
2017/02/26 Javascript
jQuery获取table表中的td标签(实例讲解)
2017/07/28 jQuery
浅谈react前后端同构渲染
2017/09/20 Javascript
一文秒懂nodejs中的异步编程
2021/01/28 NodeJs
[01:04:01]2014 DOTA2国际邀请赛中国区预选赛 5 23 CIS VS DT第一场
2014/05/24 DOTA
python3编码问题汇总
2016/09/06 Python
python使用正则表达式的search()函数实现指定位置搜索功能
2017/11/10 Python
神经网络python源码分享
2017/12/15 Python
Python安装图文教程 Pycharm安装教程
2018/03/27 Python
Python常用字符串替换函数strip、replace及sub用法示例
2018/05/21 Python
Python快速查找list中相同部分的方法
2018/06/27 Python
Django 登陆验证码和中间件的实现
2018/08/17 Python
Python数据类型之Number数字操作实例详解
2019/05/08 Python
python库matplotlib绘制坐标图
2019/10/18 Python
如何基于python操作json文件获取内容
2019/12/24 Python
Python实现银行账户资金交易管理系统
2020/01/03 Python
Python运行DLL文件的方法
2020/01/17 Python
Python如何将图像音视频等资源文件隐藏在代码中(小技巧)
2020/02/16 Python
解决springboot yml配置 logging.level 报错问题
2020/02/21 Python
css3实现书本翻页效果的示例代码
2021/03/08 HTML / CSS
Smashbox英国官网:美国知名彩妆品牌
2017/11/13 全球购物
关于赌博的检讨书
2014/01/24 职场文书
《罗布泊,消逝的仙湖》教学反思
2014/03/01 职场文书
公证委托书模板
2014/04/03 职场文书
工程合作意向书范本
2015/05/09 职场文书