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

如何构造GraphQL Mutation向Int列表添加元素并计算平均值(graph.cool&Apollo)

给Test模型的list添加值并计算平均值的实现方案

嘿,我来帮你搞定这个需求!结合Graph.cool和Apollo,你有两种可靠的实现方式,我分别给你拆解清楚:

方式一:服务端自定义Mutation(推荐,避免竞态问题)

这种方式把数组更新和平均值计算放在Graph.cool的服务端Resolver里处理,能避免多用户同时操作时的数据不一致问题。

1. 扩展GraphQL Schema

首先在你的Graph.cool Schema里添加一个自定义Mutation:

extend type Mutation {
  addIntToList(testId: ID!, value: Int!): Test
}

2. 实现Resolver逻辑

在Graph.cool的Resolver中编写处理逻辑(以JavaScript为例):

async function addIntToList(parent, { testId, value }, ctx) {
  // 1. 获取目标Test记录
  const targetTest = await ctx.db.query.test({ where: { id: testId } });
  
  // 2. 处理数组:如果原list为空则初始化,否则追加新值
  const updatedList = targetTest.list ? [...targetTest.list, value] : [value];
  
  // 3. 计算新平均值(因为average是Int类型,这里用Math.round取整,可根据需求调整)
  const total = updatedList.reduce((sum, num) => sum + num, 0);
  const updatedAverage = Math.round(total / updatedList.length);
  
  // 4. 更新Test记录并返回结果
  return ctx.db.mutation.updateTest({
    where: { id: testId },
    data: {
      list: updatedList,
      average: updatedAverage
    }
  });
}

3. Apollo客户端调用Mutation

在客户端定义Mutation文档:

mutation AddIntToList($testId: ID!, $value: Int!) {
  addIntToList(testId: $testId, value: $value) {
    id
    list
    average
  }
}

然后在你的前端代码中(比如React)使用Apollo调用:

import { useMutation } from '@apollo/client';
import ADD_INT_TO_LIST from './graphql/mutations/addIntToList';

function AddValueComponent({ testId }) {
  const [addIntToList] = useMutation(ADD_INT_TO_LIST);

  const handleAddValue = (inputValue) => {
    addIntToList({
      variables: { testId, value: inputValue }
    });
  };

  return (
    <button onClick={() => handleAddValue(7)}>
      添加7到列表并更新平均值
    </button>
  );
}

方式二:客户端先查询再更新(适合简单场景)

如果你的应用不存在多用户并发更新的场景,也可以在客户端完成计算后直接调用Graph.cool的内置updateTest Mutation:

1. 查询当前Test记录的list

先获取目标Test的现有list数据:

query GetTestDetails($testId: ID!) {
  test(where: { id: $testId }) {
    id
    list
  }
}

2. 计算新list和平均值

在客户端处理数据:

// 假设已经通过Apollo查询到了test数据
const currentList = testData.list || [];
const newList = [...currentList, 5]; // 这里的5是要添加的Int值
const totalSum = newList.reduce((sum, num) => sum + num, 0);
const newAverage = Math.round(totalSum / newList.length);

3. 调用内置updateTest Mutation

定义更新的Mutation文档:

mutation UpdateTest($testId: ID!, $newList: [Int!], $newAverage: Int!) {
  updateTest(
    where: { id: $testId },
    data: {
      list: $newList,
      average: $newAverage
    }
  ) {
    id
    list
    average
  }
}

然后在客户端执行这个Mutation即可。

注意点

  • 因为average是Int类型,计算时记得做取整处理(比如Math.round、Math.floor),避免返回浮点数导致类型错误。
  • 优先选择服务端Resolver的方式,能有效避免并发更新时的竞态条件,保证数据一致性。

内容的提问来源于stack exchange,提问作者Josh Birdwell

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:25:59