GraphQL:过滤数组中的数据

时间:2017-01-06 22:15:14

标签: graphql graphcool

我确信这是一件简单的事情,但我在GraphQL的doc或Graphcool中找不到任何东西。

假设我有一个拥有此架构的实体(新的GraphQL用户,抱歉,如果我在架构表示中出错):

Book {
  name: String!
  author: String!
  categories: [String!]
}

如何查询属于"mystery"类别的所有图书?我知道我可以使用allBooks(filter: {})进行过滤,但categories_in: ["mystery"]categories_contains: "mystery"没有做到这一点。

2 个答案:

答案 0 :(得分:10)

Category型号

想一想这种情况,创建一个Category模型绝对是可行的方法。

例如,假设您希望以后允许读者订阅他们喜欢的类别。或者,如果您想要所有现有类别的列表,该怎么办?使用字符串列表,您需要查询所有书籍,并以某种方式对所有获得的类别进行后处理。在模型级别上处理它而不是使用字符串列表会感觉更自然。

相反,您可以创建新的Category模型,并在CategoryBook之间添加多对多关系。在这种情况下,我想添加一个唯一的枚举字段tag和一个字符串字段text。 (单独一个字符串字段tag也是合适的,可能是一种品味问题。)

通过此设置,您可以轻松满足

等数据要求

哪些图书被分配到指定类别?

query {
  # query books by unique category tag
  Category(tag: MYSTERY) {
    books {
      id
    }
  }
  # query books by specific category text
  Category(filter: {
    text: "mystery"
  }) {
    books {
      id
    }
  }
}

哪些图书被分配到给定列表的至少一个类别?

query {
  allCategories(filter: {
    OR: [{
      tag: MYSTERY
    }, {
      tag: MAGIC
    }]
  }) {
    books {
      id
    }
  }
}

哪些图书被分配到给定列表的所有类别?

query {
  allCategories(filter: {
    AND: [{
      tag: MYSTERY
    }, {
      tag: MAGIC
    }]
  }) {
    books {
      id
    }
  }
}

相关过滤器

即使上述查询符合指定的数据要求,书籍也会在响应中按Category分组,这意味着我们必须在客户端上展平这些组。

通过所谓的相关过滤器,我们可以将其转变为仅根据定义其相关类别的条件获取书籍。

例如,要查询分配给给定列表中至少一个类别的图书

query {
  allBooks(filter: {
    OR: [{
      categories_some: {
        tag: MYSTERY
      },
      categories_some: {
        tag: MAGIC
      }
    }]
  }) {
    id
  }
}

答案 1 :(得分:0)

如果您对使用托管GraphQL服务感兴趣,scaphold.io已暂时使用此功能。 API中的所有连接字段都带有WhereArgs参数,该参数公开了可让您真正深入了解数据的过滤器。当你有这样的标量列表时,WhereArgs包含contains& notContains字段,允许您根据列表中的值过滤结果。这允许您进行这样的查询。

query MysteriousBooks($where:BookWhereArgs) {
  viewer {
    allBooks(where:$where) {
      edges { node { title, ... } }
    }
  }
}

# Variables
{
  "where": {
    "categories": {
      "contains": "mystery"
    }
  }
}

为了完成,您还可以进行轻微的架构重新调整,以便在不必过滤标量列表的情况下完成此工作。例如,您可以使Category节点实现类型,然后在CategoryBook之间创建连接。虽然Book可能没有多个类别,但这样您就可以发出如下查询:

query MysteriousBooks($where: CategoryWhereArgs) {
  viewer {
    allCategories(where: $where) {
      books {
        edges { node { title, ... } }
      }
    }
  }
}

# Variables
{
  "where": { 
    "name": { 
      "eq": "mystery" 
    } 
  }
}

如果您以这种方式构建架构,那么您还可以对类别中的书籍进行更多过滤,而无需遍历存档中的每本书。例如。你可以有效地索取去年写的所有神秘书籍。"

完全披露:我在Scaphold工作,虽然我爱你,但如果你不转换,就不要试一试。我很高兴看到人们尝试并喜欢GraphQL。如果您对如何在自己的服务器上实现此类行为感到好奇,请告诉我,我也很乐意为您提供帮助!

我希望这有帮助!