You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为GraphQL查询添加过滤参数至Schema及Resolver

支持复杂过滤的GraphQL Schema实现

需要实现对应以下GraphQL查询的Schema,支持limit、嵌套or/and的where过滤条件,并在Resolver中解析参数传入voyageAristowService.getVoyageData()完成MongoDB数据过滤:

query ($DateFilter: Date!, $oType: String, $voyStat: VoyageVoyageStatusCodeEnum)  {
    imos {
      voyageList (query: {
                    limit: 1
                    where:
                    {
                        or : [
                            {lastUpdateGmt: {isAfter : $DateFilter}},
                            {completeDateGmt: {isAfter : $DateFilter}}
                            ]
                        and : [
                            {oprType: {is : $oType }},
                            {voyageStatusCode: {isNot : $voyStat }}
                            ]
                    }
                })  {
          vesselCode
          lastUpdateGmt
          voyageNo
          voyageStatus
          tradeAreaName
          oprType
          completeDateGmt
          commenceDateGmt
          vessel {
              vesselType
              isActive
          }
    }
  }
}

原Schema存在的问题

  • 未定义查询中使用的VoyageVoyageStatusCodeEnum枚举类型
  • 输入类型的字段强制非空(如DateFilterInput.isAfter: Date!),不符合查询中可选参数的场景
  • 单独定义的过滤输入类型(DateFilterInput、OprTypeInput)扩展性差
  • Resolver未处理嵌套or/and条件到MongoDB查询语法的转换

修正后的Schema

#graphql
scalar Date

# 定义查询中用到的枚举类型,需补充实际业务枚举值
enum VoyageVoyageStatusCodeEnum {
  IN_PROGRESS
  COMPLETED
  CANCELLED
}

# 通用比较输入类型,覆盖is、isNot、isAfter等操作
input ComparisonInput {
  is: String
  isNot: String
  isAfter: Date
}

# 嵌套过滤条件输入,支持or/and组合
input VoyageWhereInput {
  or: [VoyageWhereInput!]
  and: [VoyageWhereInput!]
  lastUpdateGmt: ComparisonInput
  completeDateGmt: ComparisonInput
  oprType: ComparisonInput
  voyageStatusCode: ComparisonInput
}

# 查询参数输入,limit和where均设为可选
input VoyageQueryInput {
  limit: Int
  where: VoyageWhereInput
}

type AristowVessel {
  vesselType: String
  isActive: Boolean
}

type VoyageAristow {
  vesselCode: String
  lastUpdateGmt: String
  voyageNo: Int
  voyageStatus: String
  oprType: String
  tradeAreaName: String
  commenceDateGmt: Date
  completeDateGmt: Date
  vessel: AristowVessel
}

type VoyageAristowList {
  voyageList(query: VoyageQueryInput): [VoyageAristow]
}

type Query {
  imos: VoyageAristowList
}

Resolver实现示例(JavaScript)

const resolvers = {
  Query: {
    imos: () => ({})
  },
  VoyageAristowList: {
    async voyageList(parent, { query }, context) {
      // 转换GraphQL过滤条件为MongoDB查询语法
      const mongoQuery = convertToMongoQuery(query?.where || {});
      // 设置默认limit值
      const limit = query?.limit || 10;

      // 调用服务层方法传入参数
      return await context.voyageAristowService.getVoyageData({
        query: mongoQuery,
        limit
      });
    }
  }
};

// 递归转换嵌套的or/and条件到MongoDB语法
function convertToMongoQuery(whereInput) {
  const mongoQuery = {};

  // 处理or条件
  if (whereInput.or) {
    mongoQuery.$or = whereInput.or.map(convertToMongoQuery);
  }

  // 处理and条件
  if (whereInput.and) {
    mongoQuery.$and = whereInput.and.map(convertToMongoQuery);
  }

  // 处理字段级比较条件
  Object.keys(whereInput).forEach(key => {
    if (key === 'or' || key === 'and') return;

    const comparison = whereInput[key];
    const fieldQuery = {};

    if (comparison.is) fieldQuery.$eq = comparison.is;
    if (comparison.isNot) fieldQuery.$ne = comparison.isNot;
    if (comparison.isAfter) fieldQuery.$gt = comparison.isAfter;

    if (Object.keys(fieldQuery).length > 0) {
      mongoQuery[key] = fieldQuery;
    }
  });

  return mongoQuery;
}

关键说明

  • 通用ComparisonInput避免重复定义字段输入类型,提升扩展性
  • 递归处理or/and嵌套条件,将GraphQL过滤结构转换为MongoDB的$or/$and查询语法
  • 所有输入字段设为可选,匹配查询中参数可选的场景
  • 补充缺失的枚举类型,需根据实际业务值填充枚举成员

内容的提问来源于stack exchange,提问作者Himanshu Kumar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 19:45:18