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数组函数序列之array_key_exists() - 查找数组键名是否存在
Oct 29 PHP
有道搜索和IP138的IP的API接口(PHP应用)
Nov 29 PHP
PHP中使用Imagick操作PSD文件实例
Jan 26 PHP
php实现的Curl封装类Curl.class.php用法实例分析
Sep 25 PHP
php正则表达式学习笔记
Nov 13 PHP
PHP使用自定义方法实现数组合并示例
Jul 07 PHP
php实现学生管理系统
Mar 21 PHP
Laravel5权限管理方法详解
Jul 26 PHP
PHP实现简易blog的制作
Oct 24 PHP
老生常谈ThinkPHP中的行为扩展和插件(推荐)
May 05 PHP
Laravel timestamps 设置为unix时间戳的方法
Oct 11 PHP
php 的多进程操作实践案例分析
Feb 28 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对现有搜索引擎的调用
2013/06/25 PHP
linux下为php添加iconv模块的方法
2016/02/28 PHP
phpStudy 2016 使用教程详解(支持PHP7)
2017/10/18 PHP
css值转换成数值请抛弃parseInt
2011/10/24 Javascript
关于jQuery UI 使用心得及技巧
2012/10/10 Javascript
extjs表格文本启用选择复制功能具体实现
2013/10/11 Javascript
jQuery使用drag效果实现自由拖拽div
2015/06/11 Javascript
Mongoose经常返回e11000 error的原因分析
2017/03/29 Javascript
React中上传图片到七牛的示例代码
2017/10/10 Javascript
详解如何为你的angular app构建一个第三方库
2018/12/07 Javascript
基于webpack4+vue-cli3项目实现换肤功能
2019/07/17 Javascript
使用layui定义一个模块并使用的例子
2019/09/14 Javascript
JavaScript实现随机五位数验证码
2019/09/27 Javascript
JS如何把字符串转换成json
2020/02/21 Javascript
前端使用crypto.js进行加密的函数代码
2020/08/16 Javascript
[01:02:46]VGJ.S vs NB 2018国际邀请赛小组赛BO2 第二场 8.18
2018/08/19 DOTA
Python 匹配任意字符(包括换行符)的正则表达式写法
2009/10/29 Python
Python3实现将文件归档到zip文件及从zip文件中读取数据的方法
2015/05/22 Python
Python实现的朴素贝叶斯分类器示例
2018/01/06 Python
解决Pycharm运行时找不到文件的问题
2018/10/29 Python
使用python实现ftp的文件读写方法
2019/07/02 Python
使用OpCode绕过Python沙箱的方法详解
2019/09/03 Python
python——全排列数的生成方式
2020/02/26 Python
python使用Windows的wmic命令监控文件运行状况,如有异常发送邮件报警
2021/01/30 Python
Zavvi荷兰:英国大型音像制品和图书游戏零售商
2018/03/22 全球购物
如何现实servlet的单线程模式
2014/08/05 面试题
Ruby如何进行文件操作
2014/07/17 面试题
大专生自荐信
2013/10/04 职场文书
2014年庆元旦活动方案
2014/02/15 职场文书
银行优秀员工推荐信
2015/03/24 职场文书
莫言诺贝尔获奖感言(全文)
2015/07/31 职场文书
《鸟的天堂》教学反思
2016/02/19 职场文书
python爬取企查查企业信息之selenium自动模拟登录企查查
2021/04/08 Python
vue实现可拖拽的dialog弹框
2021/05/13 Vue.js
用JS创建一个录屏功能
2021/11/11 Javascript
JS class语法糖的深入剖析
2022/07/07 Javascript