There is a project that uses mongodb database. The query conditions include and and or. According to the official Thinkphp manual, use compound query (_complex). GetLastSql outputs the query statement and finds that the query condition is empty. Use string mode query (_string) , the request string query (_query) cannot meet the demand. It is estimated that there are not many users using mongodb, and thinkphp official support is not enough in this regard. Open the mongodb driver of thinkphp, Thinkphp/Extend/Driver/Db/DbMongo.class.php, and find Protected function parseThinkWhere($key,$val) method, you can find that there is no _complex in switch, that is to say, when Thinkphp uses mongodb, it does not support compound queries at all. Add:
Copy code The code is as follows:
case '_complex'://compound query
$arr = array();
foreach ($val as $nkey=>$nval){
If (Strpos ($ NKEY, '_')! = 0)
$parseArr=$this->parseWhereItem($nkey,$nval);
// Convert to objects >
$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;
The reason why it needs to be converted into an object here is because thinkphp uses the json_encode function to generate query statements. However, if the array element has a key, the json_encode function will convert the array into an object form, which mongodb cannot recognize. Because currently only or is used ,So, the code only processes or.
In addition, I found a BUG (I don’t know if it counts), in the parseWhere method:
Copy code
The code is as follows:
foreach ($where as $key=>$val){
If('_id' != $key && 0===strpos($key,'_')) {
// Parse special conditional expressions
//Original $query=$this->parseThinkWhere($key,$val);
$query = array_merge($query,$this->parseThinkWhere($key,$val));
}else{
// Security filtering of query fields
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);
}
}
}
When parsing special conditional expressions, the source code is $query=$this->parseThinkWhere($key,$val); when the special expression is not the first element in the where array, an error occurs. The $query array obtained by the code in else is gone.
http://www.bkjia.com/PHPjc/824792.htmlwww.bkjia.comtruehttp: //www.bkjia.com/PHPjc/824792.htmlTechArticleThere is a project using mongodb database. The query conditions include and and or. According to the official Thinkphp manual, use compound query ( _complex), getLastSql outputs the query statement and finds that the query condition is empty. Use the words...