如何使用 GraphQL 在 MERN 应用程序的 MongoDB 模式中插入数组字段?

Posted

技术标签:

【中文标题】如何使用 GraphQL 在 MERN 应用程序的 MongoDB 模式中插入数组字段?【英文标题】:How can you insert into an array field in a MongoDB schema in a MERN application using GraphQL? 【发布时间】:2020-05-29 21:28:23 【问题描述】:

我正在学习如何使用 MongoDB、express、react、node 和 GraphQL 进行开发。我进行了很多研究,但在掌握一个概念时遇到了问题。我的应用程序基本上是一个食谱应用程序,用户可以在其中 CRUD 食谱并拥有它们的在线食谱集合。

考虑到这一点,我创建了这个架构:

const CookbookProfileSchema = mongoose.Schema(
    fName: String,
    lName: String,
    email: type: String, lowercase: true, unique: true, required: [true, "can't be blank"], match: [/\S+@\S+\.\S+/, 'is invalid'], index: true,
    password: String,
    cookbook: [
      recipe: 
        rTitle: String,
        rDescription: String,
        rCookTime: String,
        rIngredients: [
          iName: String,
          iMeasurement: String,
        ],
        rInstructions: [
          text: String
        ]
    
  ]    
);

到目前为止,我只使用过 SQL 数据库,并且我找到了一些教程,向我展示了如何使用关系创建 2 个不同的模式,但在这一点上,使用关系数据库不是更好吗?

这些是我的类型定义:

const typeDefs = `
  type Query 
    userProfiles: [UserProfile]
    userLookup(id: ID!): [UserProfile]
    userLogin(email: String, password: String): [UserProfile]
  
  type UserProfile
    id: ID!
    fName: String
    lName: String
    email: String
    password: String
    cookbook: [Recipe]
  

  type Recipe
    rTitle: String
    rDescription: String
    rCookTime: String
    rIngredients: [Ingredient]
    rInstrctions: [Instruction]
  

  type Ingredient
    iname: String
    iMeasurement: String
  

  type Instruction
    text: String
  

  type Mutation 
    createUser(fName: String, lName: String, email: String, password: String): UserProfile
    removeUser(id: ID!): Boolean
    updateUser(id: ID!, fName: String, lName: String): Boolean
    updatePassword(id: ID!, password: String): Boolean
  
` 

到目前为止,这些是我的解析器:

const resolvers = 
  Query: 
    userProfiles: () => UserProfile.find(),
    //userLogin: async (_, id) => await UserProfile.findById(new ObjectID(id))
    userLookup: (_, id) => UserProfile.find(ObjectId(id)),
    userLogin: (_, email, password) => UserProfile.find(email, password)
  ,
  Mutation: 
    //User CRUD Mutations
    createUser: async (_, fName, lName, email, password ) => 
      const user = new UserProfile( fName, lName, email, password, cookbook: null);
      await user.save();
      return user;
    ,
    removeUser: async (_, id) => 
      await UserProfile.findByIdAndRemove(id);
      return true;
    ,
    updateUser: async (_,id, fName, lName) => 
      //Code in front end to check if the fname or lname is null
      await UserProfile.findByIdAndUpdate(id, fName , lName );
      return true;
    ,
    updatePassword: async (_, id, password) => 
      await UserProfile.findByIdAndUpdate(id,  password );
      return true;
    ,

  


const server = new GraphQLServer( typeDefs, resolvers )
mongoose.connection.once('open', function() 
  server.start(() => console.log('Server is running on localhost:4000'))
);

我打算让用户拥有许多食谱,一个食谱可以包含许多成分和许多说明,因此我可以以列表类型的格式显示它,他们可以仅针对该会话或状态进行检查。在关系数据库中,我将有一个食谱表,并让它们与用户相关联。说明和成分将与食谱有关。然后对于视图,我将简单地查询属于该用户的所有食谱来制作食谱。我怎么能在这里做类似的事情,或者我应该走关系路线?不过,我真的很想体验如何充分利用 mongodb。

任何帮助或建议将不胜感激!

【问题讨论】:

【参考方案1】:

我猜你已经发现你在 MongoDB 中没有 hasManybelongTo 等关系方法。但是,您可以使用 MongoDB 对关系类型的关系进行建模。 Check here。

不过,我应该强调 “拥有尽可能多的表来表示不同的数据实体(数据规范化)” 就像我们为 SQL 数据库所做的那样,对于 NoSQL 数据库可能不是一个好的架构设计像 MongoDB。大多数情况下,最好将彼此相关的文档放在一起。

【讨论】:

感谢您的意见!我最终混合使用了关系样式设置以及一些嵌入式对象/数组。又学到了很多,谢谢。

以上是关于如何使用 GraphQL 在 MERN 应用程序的 MongoDB 模式中插入数组字段?的主要内容,如果未能解决你的问题,请参考以下文章

当同时使用 GraphQL 时,Nodejs 和 Express 在 MERN 堆栈 Web 应用程序中的作用是啥?

部署后的 GraphQL 拒绝连接

Reactql - 使用 graphql 的 react-redux

如何在单个液滴上将不同的 MERN 应用程序部署到数字海洋?

如何使用 Multer 在 MERN Stack 应用程序中上传图像文件

如何使用后端文件夹内的前端将 MERN 应用程序部署到 Heroku