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 set_time_limit(0) 设置程序执行时间的函数
May 26 PHP
发款php蜘蛛统计插件只要有mysql就可用
Oct 12 PHP
php数组一对一替换实现代码
Aug 31 PHP
zf框架的session会话周期及次数限制使用示例
Mar 13 PHP
yii实现图片上传及缩略图生成的方法
Dec 04 PHP
php实现文本数据导入SQL SERVER
May 17 PHP
再推荐十款免费的php开发工具
Nov 09 PHP
PHP 设计模式系列之 specification规格模式
Jan 10 PHP
基于thinkPHP实现的微信自定义分享功能示例
Sep 23 PHP
PHP读取word文档的方法分析【基于COM组件】
Aug 01 PHP
PHP levenshtein()函数用法讲解
Mar 08 PHP
PHP利用DWZ.CN服务生成短网址
Aug 11 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
咖啡豆分级制度 咖啡豆等级分类 咖啡豆是按口感分类的吗?
2021/03/05 新手入门
无法在发生错误时创建会话,请检查 PHP 或网站服务器日志,并正确配置 PHP 安装最快的解决办法
2010/08/01 PHP
PHP面向对象学习笔记之一 基础概念
2012/10/06 PHP
extJs 下拉框联动实现代码
2010/04/09 Javascript
javascript下利用arguments实现string.format函数
2010/08/24 Javascript
面向对象的Javascript之三(封装和信息隐藏)
2012/01/27 Javascript
jQuery 获取/设置/删除DOM元素的属性以a元素为例
2014/05/23 Javascript
使用jQuery.wechat构建微信WEB应用
2014/10/09 Javascript
javascript实现瀑布流加载图片原理
2016/02/02 Javascript
Javascript实现通过选择周数显示开始日和结束日的实现代码
2016/05/30 Javascript
JavaScript简单验证表单空值及邮箱格式的方法
2017/01/20 Javascript
Vue实现路由跳转和嵌套
2017/06/20 Javascript
JS笛卡尔积算法与多重数组笛卡尔积实现方法示例
2017/12/01 Javascript
详解swipe使用及竖屏页面滚动方法
2018/06/28 Javascript
React styled-components设置组件属性的方法
2018/08/07 Javascript
JQuery中的常用事件、对象属性与使用方法分析
2019/12/23 jQuery
jQuery cookie的公共方法封装和使用示例
2020/06/01 jQuery
微信小程序自定义顶部组件customHeader的示例代码
2020/06/03 Javascript
[44:51]2018DOTA2亚洲邀请赛 4.4 淘汰赛 VP vs Liquid 第二场
2018/04/05 DOTA
从Python的源码来解析Python下的freeblock
2015/05/11 Python
Mac中升级Python2.7到Python3.5步骤详解
2017/04/27 Python
利用Python3分析sitemap.xml并抓取导出全站链接详解
2017/07/04 Python
python数据封装json格式数据
2018/03/04 Python
使用pycharm生成代码模板的实例
2018/05/23 Python
python Django里CSRF 对应策略详解
2019/08/05 Python
浅谈django2.0 ForeignKey参数的变化
2019/08/06 Python
Django实现WebSSH操作物理机或虚拟机的方法
2019/11/06 Python
40行Python代码实现天气预报和每日鸡汤推送功能
2020/02/27 Python
python中remove函数的踩坑记录
2021/01/04 Python
李宁官方网店:中国运动品牌
2017/11/02 全球购物
韩国江南富人区高端时尚百货商场:Galleria(格乐丽雅)
2018/03/27 全球购物
前处理班长职位说明书
2014/03/01 职场文书
销售合作意向书范本
2015/05/08 职场文书
幼儿园家长反馈意见
2015/06/03 职场文书
安全生产学习心得体会
2016/01/18 职场文书
浅谈spring boot使用thymeleaf版本的问题
2021/08/04 Java/Android