Очень медленный запрос mongo

#node.js #mongodb #mongoose

#node.js #mongodb #mongoose

Вопрос:

Я получил подобную модель в node.js / приложение moongose для моих совпадений.

 var MatchSchema   = new Schema({
    race:       { type: Number, required: true},
    type:       { type: Number, required: true},
    path:       { type: Number, required: true},
    track:      { type: Number, required: true},
    players:    [{ type: Schema.Types.ObjectId, ref: 'Player', required: true }],
    scores:     [{ type: Schema.Types.ObjectId, ref: 'Score',  required: true }],
});
  

И модель для оценки

 var ScoreSchema   = new Schema({
    player:      { type: Schema.Types.ObjectId, ref: 'Player', required: true },
    match:       { type: Schema.Types.ObjectId, ref: 'Match',  required: true },
    score:       { type: Number, required: true},
});
  

И я хочу запросить в базе данных самые высокие оценки для определенного трека, пути, типа и проигрывателя. Поле players представляет собой массив идентификаторов объектов игроков. Я делаю это так:

 // Find all matches of the right type, track, path for the player
Match.find( { path: path, track: track, players: {$in: [mongoose.Types.ObjectId(player)]}, type: type }, function(err, matches) {
    if(err || !matches) {
        // error handler...
    } else {
        var ids = matches.map(function(match) {
            return match._id;
        });
        // Find the scores from the matches and sort on score
        Score.aggregate([
            // match
            {
                "$match": { match: {$in: ids}}
            },
            // sort
            {
                "$sort": { score: -1 }
            },
            // skip
            {
                "$skip": skip
            },
            // limit
            {
                "$limit": limit
            }
        ], function(err, scores) {
            if (err || !scores) {
                // error handler
            } else {
                // do something cool
            }
        });
    }
});
  

Но это чрезвычайно медленно, требуется около 3 секунд, чтобы найти совпадения, и 1 секунда, чтобы получить / и отсортировать результаты. Я получил в общей сложности 6000 совпадений в своей базе данных и получаю 1000 документов из функции Matches.find(). Как я могу перепроектировать свои запросы и / или мои модели, чтобы улучшить производительность.

Комментарии:

1. Можете ли вы дать нам объяснение вывода запроса?

2. У вас есть индексы (как в match поле)? Насколько велика Score коллекция?

3. @freakish Первый запрос самый медленный, около 3 секунд. Нет, у меня нет индексов.

4. Индексы @Goran, несомненно, улучшат производительность. Однако 3 секунды на такую небольшую коллекцию — это слишком много даже для последовательного сканирования. Возможно, что это на самом деле связано с конфигурацией БД. Выполняется ли он на том же хосте? Или, может быть, у вас заканчиваются ресурсы, такие как память или сеть, или у вас слишком высокий iops?

5. @Sammaye Что ты имеешь в виду? Пример вывода или что я пытаюсь сделать? Я пытаюсь создать список лучших результатов для пользователя, который сыграл матчи с типом, путем, дорожкой. Тип — это тип трассы, 0, например, это бездорожье. Path — это путь трассы (трасса может иметь несколько путей для прохождения), а track — это пройденная трасса.