使用 graphql-compose-mongoose 将对象添加到 mongodb 模型中的对象数组

问题描述

我制作了一个 GraphQL API 来检索和操作 mongo 数据库中的数据。此数据表示包含 Author.ts 中显示的图书列表的作者。

Author.ts:

import { Document,Model,model,Schema } from "mongoose";
import { Ibook } from "./book";

export interface Iauthor extends Document {
    name: String;
    books: Array<Ibook>;
  }
  
const AuthorSchema: Schema = new Schema({
    name: { type: String,required: true },books: { type: Array,required: true }
  });
  
export const Author: Model<Iauthor> = model('author',AuthorSchema);

Book.ts:

import {Document,Schema} from "mongoose";

export interface Ibook extends Document {
    title: String;
    pages: Number;
  }
  
const BookSchema: Schema = new Schema({
    title: { type: String,pages: { type: Number,required: true }
  });
  
export const Book: Model<Ibook> = model('book',BookSchema);

我正在使用查询解析器和突变解析器来读取和操作这些对象。我只是迁移到 graphql-compose-mongoose 来生成解析器,而不是自己编程。我成功地迁移了每个查询和变异,直到遇到我的解析器“AssignBooktoAuthor”。这基本上是一个将书籍对象添加到作者书籍列表的解析器。我只是不知道如何让它与 graphql-compose-mongoose 一起工作。

composer.ts:

import { composeMongoose } from "graphql-compose-mongoose";
import { schemaComposer } from "graphql-compose";
import { Book } from "./models/book";
import { Author } from "./models/author";

const customizationoptions = {};
const BookTC = composeMongoose(Book,customizationoptions);
const AuthorTC = composeMongoose(Author,customizationoptions);

//in aparte file zetten prob
schemaComposer.Query.addFields({
  getAllBooks: BookTC.mongooseResolvers.findMany(),getBookById: BookTC.mongooseResolvers.findById(),getAllAuthors: AuthorTC.mongooseResolvers.findMany(),getAuthorById: AuthorTC.mongooseResolvers.findById(),});

schemaComposer.Mutation.addFields({
  CreateBook: BookTC.mongooseResolvers.createOne(),UpdateBook: BookTC.mongooseResolvers.updateById(),DeleteBook: BookTC.mongooseResolvers.removeById(),CreateAuthor: AuthorTC.mongooseResolvers.createOne(),UpdateAuthor: AuthorTC.mongooseResolvers.updateById(),DeleteAuthor: AuthorTC.mongooseResolvers.removeById(),/**AssignBooktoAuthor: AuthorTC.mongooseResolvers.///What function does this??///**/
});

const graphqlSchema = schemaComposer.buildSchema();
export default graphqlSchema;

gql.ts(服务器文件):

import { ApolloServer,gql } from "apollo-server-express";
import * as mongoose from "mongoose";
import * as express from "Express";
import * as dotenv from "dotenv";
import * as jwt from "jsonwebtoken";
import graphqlSchema from "./composer";

const app = express();
 
dotenv.config();

(async () => {
  mongoose.connect("mongodb+srv://xxxxxxx:xxxxxxx@clusterxxxxx.mongodb.net/myFirstDatabase?retryWrites=true&w=majority",{ useUnifiedTopology: true,useNewUrlParser: true});

  const server = new ApolloServer({ 
    schema: graphqlSchema,});

  await server.start();

  //verifying token 
  app.use((req,res,next) => {
    const Token = req.header('auth-token');
    try{
      (Token && jwt.verify(Token,process.env.TOKEN_SECRET)) ? next() : console.log("mw: Unauthorized");
    }catch(err){
      console.log("mw:Unauthorized");
    }
  });

  server.applyMiddleware({ app });
  
  app.listen({ port: 4000 },() =>
  console.log(`? Server ready at http://localhost:4000${server.graphqlPath}`)
  );

})();

由于对 graphql-compose-mongoose 的支持不是很大,希望有人能帮我解决这个问题!

解决方法

我自己找到了解决方案!

Graphql 支持使用对象 id 添加关系。因此,在模型中,您必须分配一个名为 authorid 之类的类型,然后添加一个具有 objectid 类型的“ref”。例如,参见 book.ts。有关 addrelation 示例,请参阅 composer.ts。

Book.ts:

export interface Ibook extends Document {
  title: String;
  pages: Number;
  author: Schema.Types.ObjectId; 
}
  
const BookSchema: Schema = new Schema({
  title: { type: String,required: true },pages: { type: Number,author: { type: Schema.Types.ObjectId,ref:"author",required: true}
});

Composer.ts:

BookTC.addRelation('author',{
  resolver: () => AuthorTC.mongooseResolvers.findById(),prepareArgs:{
    _id: source => source.author,skip: null,sort: null,},projection: {author: true},})

AuthorTC.addRelation('books',{
  resolver: () => BookTC.mongooseResolvers.findMany(),prepareArgs: {
    filter: source => ({ author: source._id }),projection: { id: true },});