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

Spring Boot GraphQL自动移除响应重复数据方案咨询

Spring Boot GraphQL 响应自动去重方案

问题分析

你遇到的情况本质是数据层返回了多条关联不同product的记录:当查询包含product字段时,每条记录因product值不同被视为独立条目;移除product字段后,这些记录的id和name完全一致,但由于实体类未基于唯一标识字段正确重写equals()和hashCode(),GraphQL无法识别它们是同一实体,导致重复返回。

可用工具库及实现方式

1. Guava Collections(推荐)

Guava提供的集合工具可快速实现有序去重,同时保留原列表的顺序:

import com.google.common.collect.Sets;
import java.util.List;
import java.util.stream.Collectors;

// 在DataFetcher或@SchemaMapping方法中处理数据
List<YourEntity> rawData = dataService.fetchData(request);
List<YourEntity> deduplicatedData = Sets.newLinkedHashSet(rawData).stream()
    .collect(Collectors.toList());

2. Apache Commons Collections

借助CollectionUtils工具类的distinct方法实现去重:

import org.apache.commons.collections4.CollectionUtils;
import java.util.List;

List<YourEntity> rawData = dataService.fetchData(request);
List<YourEntity> deduplicatedData = (List<YourEntity>) CollectionUtils.distinct(rawData);

3. GraphQL 全局自动去重(自定义Instrumentation)

如果想在GraphQL处理流程中全局自动处理去重,可以自定义Instrumentation拦截响应结果:

import graphql.ExecutionResult;
import graphql.execution.instrumentation.SimpleInstrumentation;
import graphql.execution.instrumentation.InstrumentationContext;
import graphql.execution.instrumentation.parameters.InstrumentationExecutionParameters;
import com.google.common.collect.Sets;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Component
public class DeduplicationInstrumentation extends SimpleInstrumentation {
    @Override
    public InstrumentationContext<ExecutionResult> beginExecution(InstrumentationExecutionParameters parameters) {
        return new InstrumentationContext<>() {
            @Override
            public void onCompleted(ExecutionResult result, Throwable throwable) {
                if (result != null && result.getData() instanceof Map) {
                    Map<String, Object> dataMap = (Map<String, Object>) result.getData();
                    // 针对test1字段的列表去重,可根据实际查询路径扩展逻辑
                    Object test1Data = dataMap.get("test1");
                    if (test1Data instanceof List) {
                        List<?> rawList = (List<?>) test1Data;
                        List<?> deduplicatedList = Sets.newLinkedHashSet(rawList).stream()
                            .collect(Collectors.toList());
                        dataMap.put("test1", deduplicatedList);
                    }
                }
            }
        };
    }
}

前置注意事项

无论使用哪种工具库,都需要确保实体类基于唯一标识字段重写equals()和hashCode():

import java.util.Objects;

public class YourEntity {
    private Long id;
    private String name;
    // 其他字段

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        YourEntity that = (YourEntity) o;
        return Objects.equals(id, that.id) && Objects.equals(name, that.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, name);
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 13:10:46