簡體   English   中英

Graphql過濾查詢結果

[英]Graphql filter query result

我是使用 graphql 的新手,我想改進我的 API 的一些功能,其中之一是獲得更好的過濾器。 此 API 應根據用戶將在相應 APP 中通知的成分返回一些配方,這是我正在使用的解析器:

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. 當我看到沒有返回 graphql“playground”時,當成分沒有價值時(即在與食譜不同的表中),則成分值為“null”,我什至不想返回食譜。
  2. 我無法使過濾器工作。 例如,我閱讀了查詢類型“recipe(name:[String]): [Recipe]”,但我不知道如何從那里過濾它。 這意味着,我想對我的查詢進行成分過濾,按預期過濾結果

quer: recipe(name :["sal", "açucar", "farinha"]){ id title author link category subcategory成分{名稱數量測量觀察} }

但是正如您所看到的,解析器是硬編碼的,我如何將過濾器發送給解析器?

有人可以幫我嗎? 非常感謝。

一般來說,為了處理過濾,我設置了一個基於上下文命名的Condition類型。 在這里,也許您想傳遞一個類型RecipeCondition ,它定義字段以有效過濾或限定返回的食譜,例如,基於它是否在您的數據存儲中包含成分。 這假設您將來可能想要添加其他條件(否則,只能在您的 sql 中硬編碼條件)。


    type RecipeCondition {
      ingredientsRequired: Bool
      
      // Add other condition fields here as needed
      ...
     }


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

我將在頂層處理過濾器,您最初使用 db 服務獲取食譜(而不是在成分子解析器中處理)。 您可以簡單地使用此條件,可在配方解析器 arg 上訪問,並將其傳遞給最初獲取配方數組的數據庫服務函數。 如果條件ingredientsRequiredtrue ,則適當地使用 sql 進行過濾(將需要加入成分表和 whereIn 條件——如果您傳遞了一個配方名稱數組,這可能需要迭代完成)。 通過這種方式,沒有成分的配方甚至不會命中成分子解析器(假設需要這種條件)。

感謝所有試圖提供幫助的人,所有這些評論對於指導最終答案非常重要。 我得到了一個可行的解決方案,如果可能的話,我想分享並獲得您的反饋。

首先,我改進了我的查詢解析器

  Query: {
    recipe(obj, {name}, {dataSources}, info) {
      if (name) {
        return dataSources.IngredientService.getIngredientsByName(name)
      } else {
        return db('Recipe')  
      }
    }

其次,我更改了我的 Service 以接收過濾器

 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

現在一切正常,並按預期制作過濾器。

再一次,非常感謝你們所有人。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM