如何从猫鼬模型制作graphql?

Posted

技术标签:

【中文标题】如何从猫鼬模型制作graphql?【英文标题】:how to make graphql from model of mongoose? 【发布时间】:2021-04-23 22:08:15 【问题描述】:

我正在使用 graphql 和 mongodb 将某个对象添加到数据库中。

我正在使用相同的技术向数据库添加一个对象,但是这个特定对象包含一个嵌套对象。

package.json

  "name": "workplaces",
  "version": "1.0.0",
  "main": "app.js",
  "author": "younes",
  "license": "MIT",
  "scripts": 
    "start": "nodemon app02.js"
  ,
  "dependencies": 
    "bcryptjs": "^2.4.3",
    "body-parser": "^1.19.0",
    "express": "^4.17.1",
    "express-graphql": "^0.12.0",
    "graphql": "^15.4.0",
    "mongoose": "^5.11.12"
  ,
  "devDependencies": 
    "nodemon": "^2.0.7"
  


模型位置 购买和使用数据的 mongodb 模型
const mongoose = require('mongoose');

const Schema = mongoose.Schema;

const locationSchema = new Schema(
    
        locationName:[
            
                lang:
                    type: String,
                    enum:["en","fr"],
                    required: true
                ,
                text:
                    type: String,
                    required: true
                
            
        ],
        locationType:
            type:String,
            enum:["clinic","laboratory","radiology"],
            required: true
        ,
        imageUrl:
            type:[String]
        ,
        locationMap: 
            type: 
                type: String, 
                enum: ['Point'],
                required: true
            ,
            coordinates: 
                type: [Number],
                required: true
            ,
        ,
        owner: 
            type: Schema.Types.ObjectId,
            ref: 'User'
        
    ,
    
        timestamps: true,
    
);

module.exports  = mongoose.model('location', locationSchema);
graphql
const express=require('express');
const graphqlHTTP=require('express-graphql').graphqlHTTP;
const buildSchema=require('graphql');
const mongoose=require('mongoose');
const bcrypt=require('bcryptjs');

const User=require('./models/user');

const Location=require('./models/location');


const app=express();
app.use(express.json());

app.use('/graphql',
    graphqlHTTP(
        schema:buildSchema(`

            type LocationName
                lang:String!
                text:String!
            
            input InputLocationName
                lang:String!
                text:String!
            

            type LocationMap
                type:String!
                coordinates:[Float!]
            
            input InputLocationMap
                type:String!
                coordinates:[Float!]
            

            type Location
                _id:ID!
                locationName:[LocationName!]
                locationType:String!
                imageUrl:[String!]
                locationMap:LocationMap!
                owner:User!
            
            input InputLocation
                locationName:[LocationName!]!
                locationType:String!
                imageUrl:[String!]
                locationMap:LocationMap!
            
           
           
            type User
                _id:ID!
                email:String!
                password:String
            
            input InputUser
                email:String!
                password:String!
            

            type RootQuery
                users:[User!]!
                locations: [Location!]!
            
            type RootMutation
                createUser(inputUser:InputUser): User
                createLocation(inputLocation:InputLocation): Location
            
            schema
                query: RootQuery
                mutation: RootMutation 
            
        `),
        rootValue:
            users:()=>
                return User.find()
                .then(users=>
                    console.log(users)
                    return users
                )
                .catch(err=>
                    throw err;
                )
            ,
            createLocation:(args)=>
                return User.findOne(_id:"6002cff9d32ceb25ac9e9c7e")
                .then(user=>
                    if (!user) 
                        throw new Error('User dont found.')
                    
                    else
                        const location=new Location(
                             
                                locationName:args.inputLocation.LocationName ,
                                locationType:args.inputLocation.locationType,
                                imageUrl:args.inputLocation.imageUrl,
                                locationMap:args.inputLocation.LocationMap,
                                owner:"6002cff9d32ceb25ac9e9c7e"
                            
                        );
                        return location
                        .save()
                        .then(result=>
                            console.log(result)
                            return result
                        )
                        .catch((err)=>
                            throw err;
                        )
                    
                    
                )
               
            ,
            createUser:(args)=>
                return User.findOne(email:args.userInput.email)
                .then(user=>
                    if (user) 
                        throw new Error('User exists already.')
                    
                    else
                        return bcrypt
                        .hash(args.userInput.password,12)
                        .then(hashPassword=>
                            const user=new User(
                                
                                    email:args.userInput.email,
                                    password:hashPassword
                                
                            );
                            return user
                            .save()
                            .then(result=>
                                return  ...result._doc,password:null
                            )
                            .catch((err)=>throw err;)
                        )
                        .catch((err)=>
                            throw err;
                        )
                    
                    
                )
                
            ,
            
        ,
        graphiql:true
    )
);


uri=process.env.URI
mongoose.connect(uri,
                useNewUrlParser:true
                    ,useCreateIndex:true
                    , useUnifiedTopology:true
                    )
    .then(()=>
        console.log("database connected")
        app.listen(5000);
    )
    .catch((err)=>
        console.log(err)
    )

这是我当前的 graphQL 查询:
mutation
  createLocation(inputLocation:
      locationName:[lang:"en",text:"sad",isShow:true],
      locationType:"clinic",
      imageUrl:["/images/01.png"],
      locationMap:
        type:"Point",
        coordinates:[2342342,2342345]
      
  )
  
    _id
  


错误


  "errors": [
    
      "message": "The type of InputLocation.locationName must be Input Type but got: [LocationName!]!.",
      "locations": [
        
          "line": 33,
          "column": 30
        
      ]
    ,
    
      "message": "The type of InputLocation.locationMap must be Input Type but got: LocationMap!.",
      "locations": [
        
          "line": 37,
          "column": 29
        
      ]
    
  ]

请帮忙,谢谢!

【问题讨论】:

input InputLocation 中的任何复杂类型都应该是输入类型 【参考方案1】: graphql
const express=require('express');
const graphqlHTTP=require('express-graphql').graphqlHTTP;
const buildSchema=require('graphql');
const mongoose=require('mongoose');
const bcrypt=require('bcryptjs');
const User=require('./models/user');
const Location=require('./models/location');


const app=express();
app.use(express.json());


app.use('/graphql',
    graphqlHTTP(
        schema:buildSchema(`

            type LocationName
                lang:String!
                text:String!
            
            input InputLocationName
                lang:String!
                text:String!
            

            type LocationMap
                type:String!
                coordinates:[Float!]
            
            input InputLocationMap
                type:String!
                coordinates:[Float!]!
            

            type Location
                _id:ID!
                locationName:[LocationName!]!
                locationType:String!
                imageUrl:[String!]
                locationMap:LocationMap!
                owner:User!
            
            input InputLocation_otherItems             
                locationType:String!
                imageUrl:[String!]
            
           
           
            type User
                _id:ID!
                email:String!
                password:String
            
            input InputUser
                email:String!
                password:String!
            

            type RootQuery
                users:[User!]!
                locations: [Location!]!
            
            type RootMutation
                createUser(inputUser:InputUser): User
                createLocation( inputLocation_otherItems:InputLocation_otherItems
                                inputLocationName:InputLocationName
                                inputLocationMap:InputLocationMap): Location
            
            schema
                query: RootQuery
                mutation: RootMutation 
            
        `),
        rootValue:
            users:()=>
                return User.find()
                .then(users=>
                    console.log(users)
                    return users
                )
                .catch(err=>
                    throw err;
                )
            ,
            createLocation:(args)=>
                return User.findOne(_id:"6002cff9d32ceb25ac9e9c7e")
                .then(user=>
                    if (!user) 
                        throw new Error('User dont found.')
                    
                    else
                        const location=new Location(
                             
                                locationType:args.inputLocation_otherItems.locationType,
                                imageUrl:args.inputLocation_otherItems.imageUrl,
                                locationName:[args.inputLocationName] ,
                                locationMap:args.inputLocationMap,
                                owner:"6002cff9d32ceb25ac9e9c7e"
                            
                        );
                        return location
                        .save()
                        .then(result=>
                            return result
                        )
                        .catch((err)=>
                            throw err;
                        )
                    
                    
                )
               
            ,
            createUser:(args)=>
                return User.findOne(email:args.userInput.email)
                .then(user=>
                    if (user) 
                        throw new Error('User exists already.')
                    
                    else
                        return bcrypt
                        .hash(args.userInput.password,12)
                        .then(hashPassword=>
                            const user=new User(
                                
                                    email:args.userInput.email,
                                    password:hashPassword
                                
                            );
                            return user
                            .save()
                            .then(result=>
                                return  ...result._doc,password:null
                            )
                            .catch((err)=>throw err;)
                        )
                        .catch((err)=>
                            throw err;
                        )
                    
                    
                )
                
            ,
            
        ,
        graphiql:true
    )
);


uri=process.env.URI
mongoose.connect(uri,
                useNewUrlParser:true
                    ,useCreateIndex:true
                    , useUnifiedTopology:true
                    )
    .then(()=>
        console.log("database connected")
        app.listen(5000);
    )
    .catch((err)=>
        console.log(err)
    )

变异

mutation
  createLocation(
    inputLocation_otherItems:  locationType:"clinic"
                                imageUrl:["/images/01.png"]
    
    
    inputLocationName: lang:"en"
                        text:"Life Clinic"
    

    inputLocationMap:type:"Point"
                      coordinates:[2342342,2342345]
    
  )
  
    locationNamelang
                 text
    
    locationType
    imageUrl
    locationMaptype 
                coordinates
    
   
  

结果


  "data": 
    "createLocation": 
      "locationName": [
        
          "lang": "en",
          "text": "Life Clinic"
        
      ],
      "locationType": "clinic",
      "imageUrl": [
        "/images/01.png"
      ],
      "locationMap": 
        "type": "Point",
        "coordinates": [
          2342342,
          2342345
        ]
      
    
  

【讨论】:

input InputLocation locationName:[InputLocationName!]! locationType:String! imageUrl:[String!] locationMap:InputLocationMap!

以上是关于如何从猫鼬模型制作graphql?的主要内容,如果未能解决你的问题,请参考以下文章

如何将数据从猫鼬模型显示/渲染到 ejs 文件

如何从猫鼬集合中检索模式?

是否可以从猫鼬的文档中获取模型?

从猫鼬模型传递嵌套的 JSON 数据不起作用

变异时如何修复“猫鼬模型的名称”不是graphql中的构造函数

如何从猫鼬的另一个集合中计算文档?