Mongoose заполнять виртуальные объекты - исключить localField и foreignField из результатов запроса, если foreignField имеет значение null или пустой массив - PullRequest
0 голосов
/ 19 сентября 2019

У меня простой вопрос.

В Mongoose у меня две модели.Один для Leagues, а другой для Fixtures.У каждой лиги есть уникальный id, и каждое приспособление связано с лигой с ключом league_id.

. В схеме Leagues я также определил виртуальное имя fixtures.

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

const LeagueSchema = new Schema(
    {
        _id: { type: mongoose.Schema.Types.ObjectId, select: false, auto: true },
        id: { type: Number, required: true, unique: true, index: true },
        name: { type: String, required: true },
    }
);

LeagueSchema.virtual('fixtures', {
    ref: 'fixtures',
    localField: 'id',
    foreignField: 'league_id',
    justOne: false,
});

const Leagues = mongoose.model('leagues', LeagueSchema);

const FixtureSchema = new Schema(
    {
        _id: { type: mongoose.Schema.Types.ObjectId, select: false },
        match_id: { type: Number, required: true, index: true, unique: true },
        league_id: { type: Number, required: true },
        league_name: { type: String, required: true },
        timestamp: { type: Number, required: true, index: true },
    }
);

const Fixtures = mongoose.model('fixtures', FixtureSchema);

Вот проблема.Список всех лиг очень большой, и не все из них всегда будут иметь приборы, соответствующие .populate(), поэтому я хочу исключить их из моего запроса.

Например, если я не хочу никаких приборовстарше указанной метки времени, я сделаю следующее:

(async () => {
    const target_time = 1568851200000;
    const leagues = await Leagues
        .find({})
        .populate({ path: 'fixtures', match: { timestamp: { $gte: target_time } } })
        .lean();
        console.log(leagues);
})();

Что он делает, это правильно отфильтровывает приборы по меткам времени, но это не исключает Лиги без приборов из запроса.

Вот что возвращает этот запрос:

Текущий результат :

[
    {
        id: 2,
        name: 'Champions League',
        fixtures: []
    },
    {
        id: 5,
        name: 'Europa League',
        fixtures: [
            [Object],
            [Object],
            [Object],
            [Object],
        ]
    },
    {
        id: 8,
        name: 'Premier League',
        fixtures: []
    }
];

И вот что я хочу достичь:

Желаемый результат :

[
    {
        id: 5,
        name: 'Europa League',
        fixtures: [
            [Object],
            [Object],
            [Object],
            [Object],
        ]
    },
];

Я знаю, что могу сделать что-то вроде leagues.filter(item => item.fixtures.length > 0), но этот запрос будет вызываться десятки раз в секунду, я боюсь, что запуск другогоФильтр после запроса может привести к проблемам с производительностью.

Любая помощь или возможные альтернативы приветствуются.

...