PHP MongoDB调用find方法多$and条件未全部匹配问题
问题原因
- 核心问题是查询条件冗余嵌套
$and操作符:你将两个查询条件分别包裹在独立的$and子句中,再将两个$and子句嵌套到外层$and里,属于无意义的多层嵌套。MongoDB PHP驱动在序列化这种重复嵌套同名字段操作符的PHP数组时,会出现条件解析丢失的问题,最终实际执行的查询仅保留了users.23315字段存在的判断,正则匹配条件未生效,因此返回了不符合预期的结果。 - 额外代码隐患:集合选择逻辑存在冗余写法,变量名容易混淆数据库、集合概念,提升了出错概率。
修复方案
MongoDB顶级查询条件默认就是逻辑与关系,不需要多层嵌套$and,直接将两个条件平级写入查询数组即可,两种写法都可正常生效:
写法1(推荐,隐式逻辑与,最简洁)
// 直接平级写两个条件,默认就是AND关系 $where = [ "users.23315" => ['$exists' => true], "messages.message" => new MongoDB\BSON\Regex("2019") ]; $client = new MongoDB\Client(CONNECTION_STRING); // 规范数据库、集合选择逻辑 $db = $client->sample; $collection = $db->$collection_name; // 建议将原$db_name变量重命名为$collection_name,避免和数据库概念混淆 $result = $collection->find($where);
写法2(显式$and,适合后续追加复杂逻辑的场景)
如果需要显式声明$and,直接将所有条件放到同一个$and对应的数组中即可,不要嵌套多层$and:
$where = [ '$and' => [ ["users.23315" => ['$exists' => true]], ["messages.message" => new MongoDB\BSON\Regex("2019")] ] ]; // 后续数据库、集合操作逻辑和写法1一致
补充说明
如果你的业务要求是「messages数组中同时满足message包含2019、且user_id=23315的元素存在」,而不是只要任意message包含2019即可,需要使用$elemMatch做数组元素的多条件匹配,写法如下:
$where = [ "users.23315" => ['$exists' => true], "messages" => [ '$elemMatch' => [ "message" => new MongoDB\BSON\Regex("2019"), "user_id" => 23315 ] ] ];
内容的提问来源于stack exchange,提问作者Shail
相关产品推荐
相关产品推荐

