【问题标题】:Resolver must be an object or function (Graphql Relationship)解析器必须是对象或函数(Graphql 关系)
【发布时间】:2021-09-16 18:06:27
【问题描述】:

我正在尝试在类别和产品之间建立一对多关系,但在我放置解析器后出现错误,这是我的参考代码。

错误显示:

产品解析器:

 async getProductByCategory(mainCategory, {}) {
      try {
        const product = Product.find({ mainCategory: mainCategory._id });
        if (product) {
          return product;
        } else {
          throw new Error("Product Not Found");
        }
      } catch (err) {
        throw new Error(err);
      }
    },

MainCategory 解析器:

async getCategoryByProduct(product, args) {
      try {
        const mainCategory = MainCategory.findById(product._id);
        if (mainCategory) {
          return mainCategory;
        } else {
          throw new Error("Main Category Not Found");
        }
      } catch (err) {
        throw new Error(err);
      }
    },

主解析器:

const productsResolvers = require("./products");
const mainCategoriesResolvers = require("./mainCategories");


module.exports = {
    Product: {
      mainCategory: productsResolvers.getProductByCategory,
    },
    MainCategory: {
      products: mainCategoriesResolvers.getCategoryByProduct,
    },
    Query: {
      ...productsResolvers.Query,
      ...mainCategoriesResolvers.Query,
    },
    Mutation: {
      ...productsResolvers.Mutation,
      ...mainCategoriesResolvers.Mutation,
    },
   
  };

typeDefs:

type Product {
    id: ID! 
    mainCategory: MainCategory
  }

 type MainCategory {
    id: ID!
    products: [Product]
  }

如果您需要更多代码参考,请告诉我,以便我给您。提前致谢

【问题讨论】:

  • 你使用 ORM 还是 ?
  • @Dani 是的,我使用 mongodb 来存储数据
  • @Dani 我在这里使用 MERNG 堆栈(MongoDb、Express、React、Node 和 Graphql)和 Apollo 进行状态管理

标签: mongodb mongoose graphql apollo apollo-server


【解决方案1】:

大家好,我已经为那些想了解 graphql 中的一对多关系的人解决了这个问题,这是我做的代码。

产品型号:

const { model, Schema } = require("mongoose");

const { ObjectId } = Schema.Types;

const productSchema = new Schema({
  name: String,
  mainCategory: {
    type: ObjectId,
    ref: "MainCategory",
  },
});

module.exports = model("Product", productSchema);

我们只想将 mainCategory 字段或数据设为对象,因为我们只希望每个产品都有一个类别,您看到的 ref 应该与您在这里命名的模型完全相同:

module.exports = model("MainCategory", mainCategorySchema);

对于 MainCategory 模型:

const { model, Schema } = require("mongoose");

const { ObjectId } = Schema.Types;

const mainCategorySchema = new Schema({
  products: [
    {
      type: ObjectId,
      ref: "Product",
    },
  ],
});

module.exports = model("MainCategory", mainCategorySchema);

既然你分类对不对? category 可以有多个产品,因此我们将其设为一个数组,然后像 Product 一样,我们应该使 ref 与我们命名的模型相似。

现在是 TypeDef:

type Product {
    id: ID!
    mainCategory: MainCategory!
  }

我们只将其设为 MainCategory!因为我们只想返回一个对象。

type MainCategory {
    id: ID!
    name: String!
    products: [Product!]
  }

对于 MainCategory 类型,我们将其设为 [Product!] 因为我们只想返回一个数组。

现在是 typedefs 中的查询:

type Query {
 getProducts: [Product]
 getMainCategories: [MainCategory]
}

这将获取产品和主要类别的所有数据

因为我们需要改变数据或创建它,我们可以这样做:

type Mutation {
    createProduct(
      name:String!
      mainCategory: String!
    ): Product!
     createMainCategory(
      name: String!
    ): MainCategory!
}

正如你现在所问的那样?为什么 mainCategory 是一个字符串?为什么?因为我们要发送一个对象 id 或类别的 id。

正如您所注意到的,我们没有产品 createMainCategory,因为我们将在创建产品时获取该 ID,稍后我将解释。

然后我们转到这里的解析器:

产品解析器:

const Product = require("../../models/Product");

module.exports = {
  Query: {
    async getProducts() {
      try {
        const products = await Product.find().sort({ createdAt: -1 });
        return products;
      } catch (err) {
        throw new Error(err);
      }
    },
  },
  Mutation: {
    async createProduct(_, { mainCategory }, context) {
      const newProduct = new Product({
        mainCategory,
      });

      const product = await newProduct.save();

      return product;
    },
  },
};

MainCategory 解析器:

const MainCategory = require("../../models/MainCategories");

module.exports = {
  Query: {
    async getMainCategories() {
      try {
        const mainCategories = await MainCategory.find().sort({
          createdAt: -1,
        });
        return mainCategories;
      } catch (err) {
        throw new Error(err);
      }
    },
  },
  Mutation: {
    async createMainCategory(_, { name }, context) {
      const newMainCategory = new MainCategory({
        name,
      });

      const mainCategory = await newMainCategory.save();

      return mainCategory;
    },
  },
};

最后是 index.js:

Product: {
    mainCategory: (parent) => 
    MainCategory.findById(parent.mainCategory),
},

MainCategory: {
    products: (parent) => Product.find({ mainCategory: parent._id 
}),

我们在这里定义我们使用了我使用 parent 的原因,所以我不会混淆它是产品还是 maincategory,所以在产品中你必须定义在哪种情况下我们使用 mainCategory 字段,我们使用 MainCategory模型请注意,我们使用作为产品的父级来获取作为对象 id 的 mainCategory 字段,它将返回给我们具有相同 id 的类别

对于 mainCategory 来获取我们使用 Product 模型的产品数组,请注意并找到相同的 mainCategory 和作为 mainCategory Id 的父 id,它将返回产品数组

这是你的结果: 我们首先查询产品

结果:

同样适用于 mainCategory 我们首先查询getMainCategories

那么结果:

请注意我建立了一对多关系 如果您对此有任何错误,请告诉我,我经常在 stackoverflow 上活跃,但我可能会迟到回复,但我会在看到通知时立即回复。

【讨论】:

    猜你喜欢
    • 2018-04-14
    • 1970-01-01
    • 2018-11-25
    • 2020-05-07
    • 1970-01-01
    • 2020-07-30
    • 2017-02-14
    • 2017-01-17
    • 1970-01-01
    相关资源
    最近更新 更多