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 相关文章推荐
使用 eAccelerator加速PHP代码的目的
Mar 16 PHP
利用PHP制作简单的内容采集器的代码
Nov 28 PHP
Erlang的运算符(比较运算符,数值运算符,移位运算符,逻辑运算符)
Jul 23 PHP
PHP中常用的转义函数
Feb 28 PHP
php使用google地图应用实例
Dec 31 PHP
Symfony2 session用法实例分析
Feb 04 PHP
Yii2验证器(Validator)用法分析
Jul 23 PHP
PHP实现登录注册之BootStrap表单功能
Sep 03 PHP
PHP微信支付结果通知与回调策略分析
Jan 10 PHP
php判断某个方法是否存在函数function_exists (),method_exists()与is_callable()区别与用法解析
Apr 20 PHP
php提高脚本性能的4个技巧
Aug 18 PHP
PHP实现文件上传与下载
Aug 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和ACCESS写聊天室(三)
2006/10/09 PHP
smarty中先strip_tags过滤html标签后truncate截取文章运用
2010/10/25 PHP
深入理解PHP中的count函数
2016/05/31 PHP
thinkPHP5.0框架开发规范简介
2017/03/25 PHP
laravel 解决Eloquent ORM的save方法无法插入数据的问题
2019/10/21 PHP
javascript instanceof 内部机制探析
2010/10/15 Javascript
jQuery学习笔记 获取jQuery对象
2012/09/19 Javascript
js文件Cookie存取值示例代码
2014/02/20 Javascript
jQuery的live()方法对hover事件的处理示例
2014/02/27 Javascript
百度判断手机终端并自动跳转js代码及使用实例
2014/06/11 Javascript
javascript绘制漂亮的心型线效果完整实例
2016/02/02 Javascript
Angular2内置指令NgFor和NgIf详解
2016/08/03 Javascript
Angular2从搭建环境到开发步骤详解
2016/10/17 Javascript
bootstrap vue.js实现tab效果
2017/02/07 Javascript
垃圾回收器的相关知识点总结
2018/05/13 Javascript
JS引用传递与值传递的区别与用法分析
2018/06/01 Javascript
微信小程序swiper组件实现抖音翻页切换视频功能的实例代码
2020/06/24 Javascript
python编写简单爬虫资料汇总
2016/03/22 Python
Zabbix实现微信报警功能
2016/10/09 Python
Python利用Beautiful Soup模块修改内容方法示例
2017/03/27 Python
Python实现统计给定列表中指定数字出现次数的方法
2018/04/11 Python
Django Admin实现三级联动的示例代码(省市区)
2018/06/22 Python
Django 使用easy_thumbnails压缩上传的图片方法
2019/07/26 Python
django使用JWT保存用户登录信息
2020/04/22 Python
django正续或者倒序查库实例
2020/05/19 Python
python代码如何注释
2020/06/01 Python
浅谈anaconda python 版本对应关系
2020/10/07 Python
python报错TypeError: ‘NoneType‘ object is not subscriptable的解决方法
2020/11/05 Python
详解CSS3开启硬件加速的使用和坑
2017/08/21 HTML / CSS
英国IT硬件供应商,定制游戏PC:Mesh Computers
2019/03/28 全球购物
如何使用PHP session
2015/04/21 面试题
如何减少垃圾回收让内存更加有效使用
2013/10/18 面试题
接口中的方法可以是abstract的吗
2015/07/23 面试题
医务工作者先进事迹材料
2014/01/26 职场文书
小学关爱留守儿童活动方案
2014/08/25 职场文书
Redis 异步机制
2022/05/15 Redis