排序前解析字段函数

Posted

技术标签:

【中文标题】排序前解析字段函数【英文标题】:resolve field function before sort 【发布时间】:2019-12-11 04:36:28 【问题描述】:

我正在使用 express 创建一个 graphql 服务器,并且我有一个解析器,可以根据用户查询的输入转换我的字段。 我正在使用的转换器正在返回一个函数,这是我的问题的原因。

我想按某个用户确定的字段对结果进行排序,但由于该字段是一个函数,所以它不起作用。

所以解析器看起来像这样:

const resolver = (req, param) => 
  return 
    history: async input => 
      let size = input.pageSize || 3;
      let start = (input.page || 0) * size;
      let end = start + size;
      let sortField = (input.sort || ).field || 'timestamp';
      return fs.promises.readFile("./history/blitz.json", "utf8").then(data =>
        JSON.parse(data)
          .slice(start, end)
          .map(job => historyTransformer(job))
          .sort((a,b) => a[sortField] > b[sortField] ? 1 : a[sortField] < b[sortField] ? -1 : 0)
      );
    
  ;
;

和变压器:

const historyTransformer = job => 
  return 
    ...job,
    timestamp: input =>
      dateFormat(job.timestamp, input.format || "mm:hh dd-mm-yyyy")
  ;
;

我不确定我是否遗漏了什么,但在开始排序之前是否有一种简单的方法来解决函数调用?

【问题讨论】:

【参考方案1】:

GraphQL 字段以分层方式解析,因此必须先解析 history 字段,然后才能解析其任何子字段(如 timestamp)。如果子字段的解析器转换了基础属性,并且您的意图是在父解析器中以某种方式使用该值(在这种情况下,进行一些排序),那么这很棘手,因为您正在针对执行流程工作。

因为您使用的是日期,所以您应该考虑字段的格式是否重要。作为用户,如果我按时间戳排序,我希望结果按时间顺序排序。即使将响应格式化为将时间放在首位,我也可能不希望将具有相同时间但不同年份的日期组合在一起。当然,我不知道您的业务需求,如果我们使用其他东西(例如翻译)仍然无法解决问题,这会导致同样的问题。

我能想到两种解决方案:

更新您的架构并将format 参数提升到父字段中。这更容易实现,但显然不如将参数放在它适用的字段上。 将参数保留在原处,但parse the info parameter 传递给解析器以确定父解析器内的参数值。这样,您可以将参数保留在子字段上,但将实际的格式化逻辑移动到父解析器中。

【讨论】:

以上是关于排序前解析字段函数的主要内容,如果未能解决你的问题,请参考以下文章

sql语句解析顺序和执行顺序

经典算法动画解析系列:选择排序

avcodec_send_packet函数解析

如何使用 type-graphql 解析器函数获取 graphql 后端中的选定字段?

窗口函数/解析函数

mysql group by 的用法,集合后取出指定的字段