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

如何在GraphQL Spring Boot中实现列表查询的过滤、排序与分页?

Hey Martin, let's walk through how to add filtering, sorting, and pagination (like the first:3 example you mentioned) to your allCars query using the GraphQL Spring Boot library. Here's a step-by-step breakdown that fits your existing setup:

1. Update Your GraphQL Schema

First, we need to extend the schema to define parameters for filtering, sorting, and pagination. We'll add input types for filters, enums for sorting options, and update the allCars query to accept these new parameters:

# Define input type for car filters (add more fields as needed)
input CarFilterInput {
  modelContains: String  # Filter cars where model contains this string
  brandEquals: String    # Filter cars where brand matches exactly
}

# Enum for sortable fields
enum CarSortBy {
  ID
  MODEL
  BRAND
}

# Enum for sort direction
enum SortDirection {
  ASC
  DESC
}

type Car { 
  id: ID! 
  model: String 
  brand: String 
}

type Query { 
  allCars(
    filter: CarFilterInput,       # Optional filter parameters
    sortBy: CarSortBy = ID,       # Default sort by ID
    sortDirection: SortDirection = ASC,  # Default ascending order
    first: Int                    # Optional: Return only top N results
  ): [Car]! 
}

2. Create Corresponding Java Classes

Next, map the schema's new types to Java classes so Spring can handle them:

Enums for Sorting

public enum CarSortBy {
    ID, MODEL, BRAND
}

public enum SortDirection {
    ASC, DESC
}

Filter Input DTO

import graphql.schema.annotations.GraphQLInputType;
import graphql.schema.annotations.GraphQLField;

@GraphQLInputType
public class CarFilterInput {
    private String modelContains;
    private String brandEquals;

    @GraphQLField
    public String getModelContains() {
        return modelContains;
    }

    public void setModelContains(String modelContains) {
        this.modelContains = modelContains;
    }

    @GraphQLField
    public String getBrandEquals() {
        return brandEquals;
    }

    public void setBrandEquals(String brandEquals) {
        this.brandEquals = brandEquals;
    }
}

Note: If you're using the newer Spring GraphQL integration, you might use @InputType instead of @GraphQLInputType—adjust based on your library version.

3. Modify Your Query Resolver

Now update your Query class to accept the new parameters and implement filtering, sorting, and pagination logic. Also, I noticed a small mismatch: your resolver returns List<Machine> but your schema defines Car—I've adjusted that to List<Car> here.

import org.springframework.stereotype.Component;
import java.util.List;
import java.util.stream.Collectors;

@Component
public class Query implements GraphQLQueryResolver {
    // Inject your data source (e.g., a Spring Data JPA repository)
    private final CarRepository carRepository;

    public Query(CarRepository carRepository) {
        this.carRepository = carRepository;
    }

    public List<Car> allCars(
            CarFilterInput filter,
            CarSortBy sortBy,
            SortDirection sortDirection,
            Integer first
    ) {
        // 1. Fetch all cars from your data source
        List<Car> cars = carRepository.findAll();

        // 2. Apply filtering if filter parameters are provided
        if (filter != null) {
            cars = cars.stream()
                    .filter(car -> {
                        // Filter by model containing the input string (case-insensitive)
                        if (filter.getModelContains() != null && !filter.getModelContains().isEmpty()) {
                            return car.getModel().toLowerCase().contains(filter.getModelContains().toLowerCase());
                        }
                        return true;
                    })
                    .filter(car -> {
                        // Filter by exact brand match (case-insensitive)
                        if (filter.getBrandEquals() != null && !filter.getBrandEquals().isEmpty()) {
                            return car.getBrand().equalsIgnoreCase(filter.getBrandEquals());
                        }
                        return true;
                    })
                    .collect(Collectors.toList());
        }

        // 3. Apply sorting
        cars = cars.stream()
                .sorted((car1, car2) -> {
                    int comparison = 0;
                    switch (sortBy) {
                        case MODEL:
                            comparison = car1.getModel().compareToIgnoreCase(car2.getModel());
                            break;
                        case BRAND:
                            comparison = car1.getBrand().compareToIgnoreCase(car2.getBrand());
                            break;
                        case ID:
                        default:
                            comparison = car1.getId().compareTo(car2.getId());
                            break;
                    }
                    // Reverse order if direction is DESC
                    return sortDirection == SortDirection.DESC ? -comparison : comparison;
                })
                .collect(Collectors.toList());

        // 4. Apply pagination (return first N results)
        if (first != null && first > 0) {
            int endIndex = Math.min(first, cars.size());
            cars = cars.subList(0, endIndex);
        }

        return cars;
    }
}

Performance Note

If you're dealing with large datasets, avoid filtering/sorting in memory like the example above. Instead, push these operations down to the database using Spring Data JPA Specification, Querydsl, or custom repository methods—this will be much more efficient.

4. Test Your Queries

You can now run queries like these:

Fetch top 3 cars

query {
  allCars(first: 3) {
    id
    model
  }
}

Filter, sort, and paginate

query {
  allCars(
    filter: {brandEquals: "Toyota", modelContains: "Camry"}
    sortBy: MODEL
    sortDirection: DESC
    first: 5
  ) {
    id
    model
    brand
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 12:05:55