Graphql筛选器查询结果



我是新使用graphql的,我想改进API的一些功能,其中之一是获得更好的过滤器。这个API应该返回一些基于成分的配方,用户将在各自的应用程序中通知,这是我正在使用的解析器:

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
}

过滤器正在工作,但我想改进两件事:

  1. 当我看到返回no时,graphql"操场";,当配料没有值时(在与配方不同的表中(,则配料值为"0";空";我甚至不想退回菜谱
  2. 我无法使过滤器工作。我创建了查询类型";recipe(名称:[String](:"recipe]";,例如,但我不知道如何从那里过滤它。这意味着,我想对我的查询进行成分过滤,按预期过滤结果

quer:配方(名称:["sal","açucar","fariha"]({id标题著者链接类别子类别配料{名称量测量观察}}

但正如你所看到的,解析器是硬编码的,我怎么能把过滤器发送到解析器?

有人能帮我吗?非常感谢。

通常,为了处理过滤,我设置创建一个基于上下文命名的Condition类型。在这里,您可能希望传递一个类型RecipeCondition,它定义字段来有效地过滤或确定返回的配方的范围,例如,根据它在数据存储中是否包含成分。这假设您将来可能想要添加额外的条件(否则,可能只是在sql中对条件进行硬编码(。


type RecipeCondition {
ingredientsRequired: Bool

// Add other condition fields here as needed
...
}

type Query {
recipe(name:[String], condition: RecipeCondition): [Recipe]
...
}

我会在最高层处理过滤器,在那里你最初用db服务获取食谱(而不是在配料子求解器中处理(。您可以简单地使用这个条件(可在配方解析程序arg上访问(,并将其传递给最初获取配方数组的db服务函数。如果条件ingredientsRequiredtrue,则使用sql进行适当的过滤(需要联接到配料表和where In条件中——如果您传递一个配方名称数组,则可能需要迭代完成(。这样,没有配料的配方甚至不会进入配料子求解器(假设需要该条件(。

感谢所有试图提供帮助的人,所有这些评论对于指导最终答案非常重要。我有一个可行的解决方案,如果可行的话,我想分享并获得您的反馈。

首先,我改进了我的查询解析器

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

现在一切都很好,并按预期制作过滤器。

再次感谢大家。

最新更新