Thinkphp mongodbデータベースを使用した多条件クエリー方法

3408 ワード

ある項目はmongodbデータベースを使って、検索条件はandもorもあって、Thinkphp公式マニュアルを押して、複合検索(_complex)を使って、getLastSqlは検索文を出力して、検索条件が空であることを発見します.文字列パターンでクエリ(_string)すると、要求文字列クエリ(_query)が需要を満たすことができない.mongodbを使うユーザーは多くないと思いますが、thinkphpの公式サポートも足りません.thinkphpのmongodbドライブを開く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配列は、すべてなくなりました.