laravel-mongodb如何实现FIELD形式的非升降序自定义排序
方案1:使用MongoDB聚合管道实现(推荐,数据库端处理,适合大数据量)
MongoDB 没有原生对应 MySQL FIELD() 的函数,可以通过聚合管道给字段分配自定义排序权重,再按权重排序,laravel-mongodb 中可以直接使用raw()方法构造聚合查询:
$models = Model::raw(function ($collection) { return $collection->aggregate([ [ '$addFields' => [ 'sort_weight' => [ '$switch' => [ 'branches' => [ ['case' => ['$eq' => ['$name', 'Student']], 'then' => 1], ['case' => ['$eq' => ['$name', 'Beginner']], 'then' => 2], ['case' => ['$eq' => ['$name', 'Professional']], 'then' => 3], ], 'default' => 4 // 不在指定序列内的内容默认排在最后 ] ] ] ], ['$sort' => ['sort_weight' => 1]], ['$project' => ['sort_weight' => 0]] // 查询结果移除临时生成的权重字段 ]); });
如果使用的laravel-mongodb版本支持orderByRaw对接Mongo原生语法,也可以用简化写法:
$models = Model::orderByRaw( ['$cond' => [ ['$eq' => ['$name', 'Student']], 1, ['$cond' => [ ['$eq' => ['$name', 'Beginner']], 2, ['$cond' => [ ['$eq' => ['$name', 'Professional']], 3, 4 ]] ]] ]], 'asc' )->get();
方案2:查询后用集合排序(适合小数据量)
如果查询结果集不大,可以把数据全部查出来后用Laravel集合的sortBy方法自定义排序逻辑,写法更简洁:
$sortOrder = [ 'Student' => 1, 'Beginner' => 2, 'Professional' => 3 ]; $models = Model::get()->sortBy(function ($item) use ($sortOrder) { return $sortOrder[$item->name] ?? 999; // 不在指定序列内的内容默认排在最后 });
内容的提问来源于stack exchange,提问作者user3233787
相关产品推荐
相关产品推荐

