Graphql 过滤查询结果
Graphql filter query result
我是 graphql 的新手,我想改进 API 的一些功能,其中之一是获得更好的过滤器。
这 API 应该 return 一些基于用户将在相应应用程序中告知的成分的配方,这是我正在使用的解析器:
module.exports = {
Recipe: {
async ingredients(recipe, _, { dataSources }) {
return await dataSources.IngredientService.getRecipeIngredients(recipe.id)
},
},
Query: {
recipe: async () => db('Recipe'),
ingredient: async () => db('Ingredient'),
recipeByIngredient:async () => db('Recipe'),
}}
服务
class ingredientService {
async getRecipeIngredients(recipe_id) {
const filteredRecipe = db('Ingredient')
.where({ recipe_id })
.join('Recipe', 'Recipe.id', '=', recipe_id)
.select('Recipe.*', 'Ingredient.*')
.whereIn('Ingredient.name', ["sal", "açucar"])
return await filteredRecipe
}
查询架构
type Query {
recipe(name:[String]): [Recipe]
ingredient:[Ingredients]
recipeByIngredient(ingredients:String):[Ingredients]
}
type Recipe {
id: Int
title: String!
author: String
link: String
category: String
subcategory:String
ingredients:[Ingredients]
}
type Ingredients{
id:Int
name:String
quantity:Float
measure:String
observation:String
}
过滤器工作正常,但我想改进 2 件事:
- 当我看到 return 没有 graphql“游乐场”时,当配料没有价值时(与食谱不同 table),则配料值为“ null”,我什至不想 return 食谱。
- 我无法使过滤器工作。例如,我重述了查询类型“recipe(name:[String]): [Recipe]”,但我不知道如何从那里过滤它。这意味着,我想对我的查询进行成分过滤,按预期过滤结果
疑问:
食谱(名称:[“sal”,“açucar”,“farinha”]){
ID
标题
作者
link
类别
子类别
配料{
名称
数量
措施
观察
}
}
但是如您所见,解析器是硬编码的,我如何将过滤器发送到解析器?
有人可以帮我吗?
非常感谢。
一般来说,为了处理过滤,我设置创建一个 Condition
类型,根据上下文命名。在这里,您可能想要传递一个类型 RecipeCondition
,它定义字段以有效地过滤或限定返回的食谱,例如,基于它是否在您的数据存储中有成分。这假设您将来可能想添加其他条件(否则,可以在 sql 中硬编码条件)。
type RecipeCondition {
ingredientsRequired: Bool
// Add other condition fields here as needed
...
}
type Query {
recipe(name:[String], condition: RecipeCondition): [Recipe]
...
}
我会在您最初使用数据库服务获取食谱的顶层处理过滤器(而不是在配料子解析器中处理)。您可以简单地使用此条件,可在配方解析器 arg 上访问,并将其传递给最初获取配方数组的数据库服务函数。如果条件 ingredientsRequired
是 true
,则使用 sql 进行适当过滤(将需要加入配料 table 和 whereIn 条件——如果您传递了一组食谱名称,这可能需要反复完成)。这样,没有配料的配方甚至不会命中配料子解析器(假设需要该条件)。
感谢所有试图提供帮助的人,所有这些评论对于指导最终答案非常重要。
我找到了一个可行的解决方案,如果可能的话,我想分享并征求您的反馈。
首先,我改进了我的查询解析器
Query: {
recipe(obj, {name}, {dataSources}, info) {
if (name) {
return dataSources.IngredientService.getIngredientsByName(name)
} else {
return db('Recipe')
}
}
其次,我更改了我的服务以接收过滤器
async getIngredientsByName(name) {
const filteredRecipe = db('Ingredient')
//.where({ recipe_id })
.join('Recipe', 'Recipe.id', '=', 'Ingredient.recipe_id')
.select('Recipe.*', 'Ingredient.name', 'Ingredient.quantity', 'Ingredient.measure','Ingredient.observation')
.whereIn('Ingredient.name', name)
return await filteredRecipe
现在一切正常并按预期制作过滤器。
再次感谢大家。
我是 graphql 的新手,我想改进 API 的一些功能,其中之一是获得更好的过滤器。 这 API 应该 return 一些基于用户将在相应应用程序中告知的成分的配方,这是我正在使用的解析器:
module.exports = {
Recipe: {
async ingredients(recipe, _, { dataSources }) {
return await dataSources.IngredientService.getRecipeIngredients(recipe.id)
},
},
Query: {
recipe: async () => db('Recipe'),
ingredient: async () => db('Ingredient'),
recipeByIngredient:async () => db('Recipe'),
}}
服务
class ingredientService {
async getRecipeIngredients(recipe_id) {
const filteredRecipe = db('Ingredient')
.where({ recipe_id })
.join('Recipe', 'Recipe.id', '=', recipe_id)
.select('Recipe.*', 'Ingredient.*')
.whereIn('Ingredient.name', ["sal", "açucar"])
return await filteredRecipe
}
查询架构
type Query {
recipe(name:[String]): [Recipe]
ingredient:[Ingredients]
recipeByIngredient(ingredients:String):[Ingredients]
}
type Recipe {
id: Int
title: String!
author: String
link: String
category: String
subcategory:String
ingredients:[Ingredients]
}
type Ingredients{
id:Int
name:String
quantity:Float
measure:String
observation:String
}
过滤器工作正常,但我想改进 2 件事:
- 当我看到 return 没有 graphql“游乐场”时,当配料没有价值时(与食谱不同 table),则配料值为“ null”,我什至不想 return 食谱。
- 我无法使过滤器工作。例如,我重述了查询类型“recipe(name:[String]): [Recipe]”,但我不知道如何从那里过滤它。这意味着,我想对我的查询进行成分过滤,按预期过滤结果
疑问: 食谱(名称:[“sal”,“açucar”,“farinha”]){ ID 标题 作者 link 类别 子类别 配料{ 名称 数量 措施 观察 } }
但是如您所见,解析器是硬编码的,我如何将过滤器发送到解析器?
有人可以帮我吗? 非常感谢。
一般来说,为了处理过滤,我设置创建一个 Condition
类型,根据上下文命名。在这里,您可能想要传递一个类型 RecipeCondition
,它定义字段以有效地过滤或限定返回的食谱,例如,基于它是否在您的数据存储中有成分。这假设您将来可能想添加其他条件(否则,可以在 sql 中硬编码条件)。
type RecipeCondition {
ingredientsRequired: Bool
// Add other condition fields here as needed
...
}
type Query {
recipe(name:[String], condition: RecipeCondition): [Recipe]
...
}
我会在您最初使用数据库服务获取食谱的顶层处理过滤器(而不是在配料子解析器中处理)。您可以简单地使用此条件,可在配方解析器 arg 上访问,并将其传递给最初获取配方数组的数据库服务函数。如果条件 ingredientsRequired
是 true
,则使用 sql 进行适当过滤(将需要加入配料 table 和 whereIn 条件——如果您传递了一组食谱名称,这可能需要反复完成)。这样,没有配料的配方甚至不会命中配料子解析器(假设需要该条件)。
感谢所有试图提供帮助的人,所有这些评论对于指导最终答案非常重要。 我找到了一个可行的解决方案,如果可能的话,我想分享并征求您的反馈。
首先,我改进了我的查询解析器
Query: {
recipe(obj, {name}, {dataSources}, info) {
if (name) {
return dataSources.IngredientService.getIngredientsByName(name)
} else {
return db('Recipe')
}
}
其次,我更改了我的服务以接收过滤器
async getIngredientsByName(name) {
const filteredRecipe = db('Ingredient')
//.where({ recipe_id })
.join('Recipe', 'Recipe.id', '=', 'Ingredient.recipe_id')
.select('Recipe.*', 'Ingredient.name', 'Ingredient.quantity', 'Ingredient.measure','Ingredient.observation')
.whereIn('Ingredient.name', name)
return await filteredRecipe
现在一切正常并按预期制作过滤器。
再次感谢大家。