如何在查询模型时对其hasMany关联关系的返回数据进行过滤?
解决方案
以下是基于GraphQL + Laravel技术栈的实现方案,可实现查询主模型的同时仅返回符合过滤条件的关联数据,主模型不会受关联数据是否存在的影响:
1. 修改GraphQL Schema定义
给analytic关联字段新增过滤参数,可直接使用Lighthouse框架提供的@whereConditions指令,快速实现多条件过滤能力:
type Location { id: ID! parent_id: ID name: String! admin_level: Int! country: String! # 新增过滤参数,columnsEnum可根据自己的字段枚举调整 analytic(filter: QueryConditions @whereConditions(columnsEnum: "AnalyticColumn")): [LocationAnalytic!]! @hasMany }
2. 调整查询语句
在关联字段处传入过滤参数,改造后的查询语句如下:
query($id:Int!, $analyticFilter: QueryConditions!) { location (id: $id) { id parent_id name admin_level country analytic(filter: $analyticFilter) { id category_id total_listings_count new_listings_count expired_listings_count created_at } } }
3. 适配请求变量
调整你当前的变量结构,和查询参数对应即可:
{ "id": 100075, "analyticFilter": { "AND": [ { "column": "CATEGORY_ID", "operator": "EQ", "value": 390005 } ] } }
自定义Resolver实现(非Lighthouse场景)
如果是自己写Resolver处理逻辑,直接在预加载关联时加闭包过滤即可:
public function getLocation($root, array $args) { return Location::with(['analytic' => function ($query) use ($args) { // 按传入的过滤条件构造查询 if (!empty($args['analyticFilter']['AND'])) { foreach ($args['analyticFilter']['AND'] as $condition) { $query->where( strtolower($condition['column']), $condition['operator'], $condition['value'] ); } } }])->findOrFail($args['id']); }
以上方案完全满足需求:主模型Location会完整返回,关联的LocationAnalytic仅返回符合条件的条目,即使没有符合条件的关联数据,主模型也不会被过滤。
内容的提问来源于stack exchange,提问作者Can Atuf Kansu
相关产品推荐
相关产品推荐

