Выберите поле, заполненное в Mongoose - PullRequest
0 голосов
/ 10 апреля 2020

Мне нужно отфильтровать поля полученного результата как заполненные функцией mon goose select(). Мне нужны только поля title, content, image объекта Post и name и avatar объекта User.

В пользовательской схеме у меня есть создал virtual, который ссылается на поле userId схемы Post.

// ========= 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": "$2b$12$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": "$2b$12$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"
}

Ответы [ 2 ]

0 голосов
/ 10 апреля 2020

Вы можете следовать этому коду

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


**Also You can use Aggregate: $project operator**
0 голосов
/ 10 апреля 2020

вы можете использовать метод выбора, чтобы выбрать то, что вам нужно из текущей коллекции

относительно заполненного поля, вы можете передать объект в метод заполнения, чтобы указать путь, который вы будете заполнять, и выбрать, какие элементы из этой коллекции

ваш запрос должен быть примерно таким

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

обратите внимание, что нам нужно выбрать userId при первом выборе, чтобы мы могли использовать его в функции заполнения

...