mongoose使用populate合并对数据库的request

populate

Mongoose的populate()函数是一个强大的工具,让你可以关联其他collectionsdocuments
关联的好处在于可以合并对数据库的request。

  • 使用populate()之前
const recipeSchema = new mongoose.Schema(
 {
  title: {
      type: String,
      required: true,
      minlength: 6,
      maxlength: 255
    },
  materials: [
      {
        type: Schema.Types.ObjectId,
        ref: 'Material',
        required: false
      }
    ]
  });
const materialSchema = new mongoose.Schema(
  {
    name: {
      type: String,
      required: true
    }
  });
const Material = mongoose.model('material', materialSchema);
const Recipe = mongoose.model('recipe', recipeSchema);

const resolverMap = {
  Query: {
    recipes() {
      console.log('Query.recipes info');
      return Recipe.find();
    },
    recipe(_, { id }) {
      return Recipe.findForOp(id);
    }
  }
};

在graphql的playgroud中获取recipes

query{
  recipes{
    id
    title
    image
    materials{
      name
    }
  }
}

得到命令行中console.log() 输出的信息

Query.recipes info
Query.materials info:  5bec111425c2be15fbcefec4
Query.materials info:  5becc04d25c2be15fbcefecb
Query.materials info:  5bf0b52e7dbe97559cfd0d52

可以看到总共进行了4次和数据库的交互

  • 使用populate()之后
const recipeSchema = new mongoose.Schema(
 {
  title: {
      type: String,
      required: true,
      minlength: 6,
      maxlength: 255
    },
  materials: [
      {
        type: Schema.Types.ObjectId,
        ref: 'Material',
        required: false
      }
    ]
  });
const resolverMap = {
  Recipe: {
  },
  Query: {
    recipes() {
      console.log('Query.recipes info');
      return Recipe.find().populate({ path: 'materials', select: 'name' });
    },
    recipe(_, { id }) {
      return Recipe.findForOp(id);
    }
  }
};

同样的graphql请求,命令行中的输出结果为

Query.recipes info

即只有一次数据请求

你可能感兴趣的:(mongoose使用populate合并对数据库的request)