过滤嵌套字段,或将类型映射到查询

Posted

技术标签:

【中文标题】过滤嵌套字段,或将类型映射到查询【英文标题】:Filtering nested fields, or mapping types to queries 【发布时间】:2019-09-01 09:55:27 【问题描述】:

请原谅这个可能很基本的问题。我使用 GraphQL SPQR 来实现产品 DTO 的获取,如下所示:

@GraphQLQuery(name = "products")
public Page<ProductEntity> getProducts(@GraphQLArgument(name = "count", defaultValue = "10") int count, @GraphQLArgument(name = "offset") int offset) 
    Pageable queryPage = PageRequest.of(offset, count);
    return productRepository.findAll(queryPage);

请注意,我正在使用此查询对我的数据存储库进行分页。

我的 DTO 的设置方式可以查询如下:

products(count: 10, offset: 0) 
    store 
        products /* attempting to query using the count and offset parameters here is invalid*/ 
            productName
        
    

在第二种类型(商店)下,我再次获取产品列表。如何告诉 GraphQL 以与获取第一个产品列表相同的方式获取第二个嵌套的产品列表?

我正在想象能够将GraphQLQuery 绑定到我的ProductEntityDAO 类或类似的东西,以便针对该类型的提取都可以以相同的方式解决。

感谢您的帮助。

编辑:

感谢Kaqqao。该解决方案运行良好,我需要为“拥有产品的实体”的一般情况解决此问题。

为此,我在我的产品实体上定义了一个接口,如下所示:

@GraphQLInterface(name = "hasProducts", implementationAutoDiscovery = true)
public interface ProductEdge 
    Collection<ProductEntity> getProducts();

然后,我通过在需要执行此操作的实体上实现此接口,使与产品列表有连接的实体以通用方式获取它:

public class CommercialPartnerEntity implements ProductEntity.ProductEdge

在我的存储库中:

@Query("select child from CommercialPartnerEntity p inner join p.products child where p = :parent")
@GraphQLQuery(name = "relatedProducts")
Page<ProductEntity> findBy(@Param("parent") ProductEntity.ProductEdge parent, Pageable pageable);

允许我在我的服务中做这样的事情:

@GraphQLQuery(name = "productsList")
public Page<ProductEntity> getProducts(@GraphQLContext ProductEntity.ProductEdge hasProductsEntity, @GraphQLArgument(name = "count", defaultValue = "10") int count, @GraphQLArgument(name = "offset") int offset) 
    Pageable queryPage = PageRequest.of(offset, count);
    return productRepository.findBy(hasProductsEntity, queryPage);

因此,我以一种通用的方式为任何特定类型定义了我的解析器。很想听听其他人对解决方案的看法。

当实现“按名称过滤”之类的东西时,我想这也会非常有用。

【问题讨论】:

经过一番调查,看来我应该扩展 Spring 数据存储库的功能。如果成功,将更新问题。 【参考方案1】:

如果我没听错,您正在寻找一种方法来调用外部方法来解析store.products。如果是这种情况,使用@GraphQLContext 很容易实现。

你可以例如做类似的事情:

//Any class with queries
public class ProductService 

    @GraphQLQuery(name = "products")
    public Page<ProductEntity> getProducts(@GraphQLContext Store store, @GraphQLArgument(name = "count", defaultValue = "10") int count, @GraphQLArgument(name = "offset") int offset) 
        //your logic here, maybe delegating to the existing getProducts method
    

如果Store 已经有getProducts,您可能想要@GraphQLIgnore 它,但不是强制性的。

如果您询问如何在store.products 中将相同的参数传递给products,请查看我的答案here。您可以使用@GraphQLEnvironment ResolutionEnvironment 注入ResolutionEnvironment,如果需要,您可以从那里获取DataFetchingEnvironment

【讨论】:

谢谢。我也对您的答案做了一些改进,请参阅更新后的问题。

以上是关于过滤嵌套字段,或将类型映射到查询的主要内容,如果未能解决你的问题,请参考以下文章

在 AWS Amplify GraphQL DynamoDB 中按另一个表的字段(也称为交叉表或嵌套过滤)过滤列表查询

如何使用 Mongoose 查询过滤到数组类型字段中具有指定值的文档?

Elasticsearch - 将普通字段过滤器添加到嵌套字段聚合

MongoDb 聚合基于 ids 过滤列表并将此过滤列表映射到另一个字段

如何对 Hasura 中的 ARRAY 字段类型运行 GraphQL 过滤器查询?

如何使用映射或过滤器而不是列表推导过滤特定值的嵌套字典(pythonic 方式)?