SQL转MongoDB查询结果为空,请求修正PHP查询代码
从SQL转换为MongoDB查询的修正方案
原SQL查询语句
SELECT user_id, resubmit_count, user_id, id, title, tags, added_date FROM admin_self_care WHERE status='1' AND user_type='2' AND selfcare_reviewer_status='0' AND user_id='{$_SESSION['login_user_id']}' group by id order by id desc
用户尝试的MongoDB代码(返回空结果)
$filter = [ 'status' => '1', 'user_type' => '2', 'selfcare_reviewer_status' => '0', 'user_id' => $_SESSION['login_user_id'] ]; $options = [ 'sort' => ['id' => -1], 'projection' => [ 'user_id' => 1, 'resubmit_count' => 1, 'id' => 1, 'title' => 1, 'tags' => 1, 'added_date' => 1 ], 'collation' => ['locale' => 'en'], ]; $result = $collection->find($filter, $options);
问题分析与修正方案
关键问题点
- 数据类型不匹配:SQL中用字符串值(如
'1')匹配,但MongoDB中对应字段可能存储为数字类型(如1),这是查询无结果的最常见原因。 - 冗余配置干扰:无特殊排序/匹配需求时,
collation配置可能影响查询结果,建议移除。 - GROUP BY逻辑处理:原SQL的
GROUP BY id若因id是主键(唯一值)则完全冗余;若存在重复id的文档,需用聚合管道实现分组。 - 游标未遍历:MongoDB的
find返回游标,必须遍历才能获取实际数据,否则会误以为结果为空。
修正代码1:id为唯一主键(无需分组)
假设id是唯一标识,且数据库中status、user_type等字段为数字类型:
$filter = [ 'status' => 1, 'user_type' => 2, 'selfcare_reviewer_status' => 0, 'user_id' => $_SESSION['login_user_id'] ]; $options = [ 'sort' => ['id' => -1], 'projection' => [ 'user_id' => 1, 'resubmit_count' => 1, 'id' => 1, 'title' => 1, 'tags' => 1, 'added_date' => 1, '_id' => 0 // 可选:移除MongoDB默认的_id字段,与SQL结果对齐 ] ]; $result = $collection->find($filter, $options); // 遍历游标获取结果 foreach ($result as $doc) { print_r($doc); }
修正代码2:需模拟GROUP BY id(存在重复id文档)
若数据库中存在重复id的文档,用聚合管道实现分组逻辑,取每组第一个匹配的文档:
$pipeline = [ // 匹配过滤条件 [ '$match' => [ 'status' => 1, 'user_type' => 2, 'selfcare_reviewer_status' => 0, 'user_id' => $_SESSION['login_user_id'] ] ], // 按id分组,保留每组第一个文档的字段 [ '$group' => [ '_id' => '$id', 'user_id' => ['$first' => '$user_id'], 'resubmit_count' => ['$first' => '$resubmit_count'], 'title' => ['$first' => '$title'], 'tags' => ['$first' => '$tags'], 'added_date' => ['$first' => '$added_date'] ] ], // 按id降序排序 [ '$sort' => ['_id' => -1] ], // 重命名_id为id,与SQL结果字段对齐 [ '$project' => [ 'id' => '$_id', 'user_id' => 1, 'resubmit_count' => 1, 'title' => 1, 'tags' => 1, 'added_date' => 1, '_id' => 0 ] ] ]; $result = $collection->aggregate($pipeline); // 遍历聚合结果 foreach ($result as $doc) { print_r($doc); }
内容的提问来源于stack exchange,提问作者Nilesh
相关产品推荐
相关产品推荐

