Select 填充在 Mongoose 中的字段

Select field populated in Mongoose

我需要过滤获得的结果的字段,用 mongoose select() 函数填充。我只需要 Post 对象的 titlecontentimage 字段以及 User 对象的 nameavatar对象。

在用户模式中,我创建了一个 virtual,它引用 Post 模式的 userId 字段。

// ========= MODELS =============

const mongoose = require('mongoose');

const { Schema } = mongoose;

const userSchema = new Schema({
    name: { type: String, trim: true, required: true },
    email: { type: String, trim: true, required: true },
    password: { type: String, trim: true, required: true },
    description: { type: String, trim: true, required: true },
    avatar: { type: String, trim: true, required: true },
});

userSchema.virtual('ownerPost', {
  ref: 'Post',
  localField: '_id',
  foreignField: 'userId',
});

const postSchema = new Schema(
  {
    title: { type: String, trim: true, lowercase: true, required: true },
    content: { type: String, required: true },
    summary: {type: String, required: true },
    image: { type: String, trim: true, required: true },
    userId: { type: Schema.Types.ObjectId, ref: 'User', required: true }
  });

const Post = mongoose.model('Post', postSchema);
const User = mongoose.model('User', userSchema);

// ========= CONTROLLERS =============

const getPostById = async (req, res, next) => {
  try {
    const { id } = req.params;
    const post = await Post.findById(id)
      .populate('userId')
      // it doesn't work
      // .select(['title', 'content', 'image', 'userId.name', 'userId.avatar']);
      // it doesn't work
      // .select(['title', 'content', 'image', 'name', 'avatar']);

    return res.status(200).json(post);
  } catch (error) {
    return next(error);
  }
};

// ========= RESPONSE WITHOUT SELECT IN GET POST BY ID =============

{
    "title": "Example Title",
    "content": "<h1>This is content</h1>",
    "summary": "<h4>This is summary</h4>",
    "image": "https://upload.wikimedia.org/wikipedia/commons/0/02/Great_Wave_off_Kanagawa_-_reversed.png",
    "userId": {
        "name": "peter",
        "email": "peter80@gmail.com",
        "password": "b$LaJWX1/A3ATq4c/tgNIs.uwhnpZGwsqBePFLxIFCDa9gwjitcalda",
        "description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor.",
        "avatar": "https://pngimage.net/wp-content/uploads/2018/05/avatar-profile-png-2.png",
        "id": "5e9066e5bc3e6a415134396e"
    },
    "id": "5e90677cbc3e6a4151343970"
}

// ========= RESPONSE WITH SELECT IN GET POST BY ID =============

{
    "title": "titulo de ejemplo",
    "content": "<h1>Esto es un contenido de ejemplo</h1>",
    "image": "https://upload.wikimedia.org/wikipedia/commons/0/02/Great_Wave_off_Kanagawa_-_reversed.png",
    "userId": {
        "name": "peter",
        "email": "peter80@gmail.com",
        "password": "b$LaJWX1/A3ATq4c/tgNIs.uwhnpZGwsqBePFLxIFCDa9gwjitcalda",
        "description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor.",
        "avatar": "https://pngimage.net/wp-content/uploads/2018/05/avatar-profile-png-2.png",
        "id": "5e9066e5bc3e6a415134396e"
    },
    "id": "5e90677cbc3e6a4151343970"
}

您可以使用 select 方法 select 从当前集合中获取您需要的内容

关于填充字段,您可以将一个对象传递给填充方法以指示您将填充的路径,并select从该集合中选择哪些项目

你的查询应该是这样的

Post.findById(id).select('title content image userId').populate({ path: 'userId', select: 'name avatar' })

您可以遵循此代码

const post = await Post.findById(id)
      .select("+title +content +image")
      .populate('userId')


**Also You can use Aggregate: $project operator**