Mongoose - поиск заполненных вложенных ссылок с использованием текущего объекта - PullRequest
0 голосов
/ 05 сентября 2018

Название может вводить в заблуждение (возможно), но у меня есть следующий сценарий в моем API отдыха

Employees = new Schema({
    name: String,
    meetings: [{ type: Schema.Types.ObjectId, ref: 'meetings'}],
    // [...]
});

Meetings = new Schema({
    date: Date,
    employees: [{ type: Schema.Types.ObjectId, ref: 'employees'}],
    // [...]
});

У меня есть две модели, одна для сотрудников, одна для встреч.

  • каждый сотрудник будет иметь список всех встреч, которые он посетил.
  • каждое собрание будет иметь список всех людей, которые посетили его.

Используя express, я определил маршрут, по которому я хочу собрать всех людей. Я могу заполнить массив собраний данными из объекта Meeting, к которому они относятся, и в качестве бонуса хочу заполнить массив сотрудников внутри этого массива собраний сотрудниками, которые присутствовали на собрании (надеюсь, это имеет смысл)

Это было достаточно просто :

// some express code
// [...]
//

router.get('/employees', (req, res) => {
    Employees.find()
        .populate({
            path: 'meetings',
            select: ['_id', 'date', 'employees'], // i exclude any other data I don't need
            populate: {
                path: 'employees',
                select: ['_id', 'name'],
            },
        })
        .then(result => res.json(result))
        .catch(e => res.status(500).json({ error: e.message || e }));
});

это работает как задумано. Единственное мое недовольство в том, что внутри массива employees внутри meetings я также получаю текущего сотрудника, например,

[
    {
        _id: 'employeeId1',
        name: 'John',
        meetings: [
            {
                _id: 'meetingId1',
                date: '2018-09-05',
                employees: [
                    {
                        _id: 'employeeId1',
                        name: 'John',
                    },
                    {
                        _id: 'employeeId2',
                        name: 'Sarah',
                    },
                ]
            }
        ]
    }
]

Я бы хотел сказать Мангузу, чтобы он не считал текущего сотрудника, чего я могу достичь с помощью findOne

router.get('/employees/:id', (req, res) => {
    Employees.findOne({ _id: req.params.id })
        .populate({
            path: 'meetings',
            select: ['_id', 'date', 'employees'],
            populate: {
                path: 'employees',
                select: ['_id', 'name'],
                match: {
                    _id: { $ne: req.params.id }
                }
            },
        })
        .then(result => res.json(result))
        .catch(e => res.status(500).json({ error: e.message || e }));
});

что правильно мне дает

[
    {
        _id: 'personId1',
        name: 'John',
        meetings: [
            {
                _id: 'meetingId1',
                date: '2018-09-05',
                employees: [
                    {
                        _id: 'personId2',
                        name: 'Sarah',
                    },
                ]
            }
        ]
    }
]

но в момент find(...).populate(...) я не имею никакой ссылки на текущий объект ... не так ли?

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

...