Пн goose: Как добавить фильтр в .select () - PullRequest
1 голос
/ 16 апреля 2020

В моем примере я нахожу данные компании, которые принадлежат пользователю. Затем я выбираю массив board_posts из найденной компании. Это позволяет мне получить все сообщения в этом массиве. Но сейчас мне нужно только получать сообщения в board_posts, которые имеют author_id, совпадающий с user_id. Есть ли способ добавить фильтр для выбора, чтобы сделать это?

router.get('/posts',  passport.authenticate('jwt', { 
    session: false 
}), (req, res) => {
    let user = req.user;
    let user_id = user._id;

    Company.findById(user.company_id)
        .select('board_posts')//filter board_posts if( board_posts.author_id == user_id)
        .then(result => {
            res.status(200).json(result.board_posts);
        })
        .catch(error => {
            console.log(error)
        });
});

Схема компании:

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const BoardPostSchema = new Schema({
    name: {
        type: String
    },
    author_id: {
        type: Schema.Types.ObjectId
    }
});

const CompanySchema = new Schema({
    company_name: {
        type: String
    },
    board_posts: [BoardPostSchema],
});

module.exports = Company = mongoose.model('companies', CompanySchema);

Это результат, если я удаляю select и просто console.log результат

{ 
    _id: 5e98255f1c9d440000eefaf5,
    company_name: 'Fyber',
    board_posts:[
        { 
            _id: 5e98500c29a6915d84745879,
            name: 'hello',
            author_id: 5e847e3822a416106c4cb999 
        },
        {
            _id: 5e9852256e455a4814e54d36,
            company_name: 'test',
            author_id: 5e847e3822a416106c4cb999 
        },
        { 
            _id: 5e98532770ea8748c41a6dc1,
            company_name: 'what',
            author_id: 5e847e3822a416106c4cb360 
        },
        { 
            _id: 5e9859b7c41ea60fd4e433ca,
            name: 'another',
            author_id: 5e847e3822a416106c4cb360 
        },
    ] 
}

1 Ответ

2 голосов
/ 16 апреля 2020

Вы можете сделать это с помощью $ filter агрегации:

const { ObjectId } = require("mongoose").Types;

router.get("/posts", passport.authenticate("jwt", { session: false }), (req, res) => {
  let user = req.user;
  let user_id = user._id;

  Company.aggregate([
    {
      $match: {
        _id: ObjectId(user.company_id),
      },
    },
    {
      $project: {
        board_posts: {
          $filter: {
            input: "$board_posts",
            as: "item",
            cond: {
              $eq: ["$$item.author_id", ObjectId(user_id)],
            },
          },
        },
      },
    },
  ])
    .then((result) => {
      if (result) {
        res.status(200).json(result[0].board_posts);
      } else {
        res.status(404).json({ msg: "Company Not Found" });
      }
    })
    .catch((error) => {
      console.log(error);
    });
});

Playground

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...