猫鼬聚合管道每次返回不同的结果

时间:2020-05-25 09:25:30

标签: node.js mongoose

我有一个聚合管道,应该返回一个有序数组。然而。每次我进行API校准时,每次都会返回不同的顺序。这是我的代码

    exports.getResultToCompetition = asyncHandler(async (req, res, next) => {
  const data = await Result.aggregate([
    {
      $match: { competition: mongoose.Types.ObjectId(req.params.competitionId) },
    },
    {
      $project: {
        points: 1,
        kilogramms: 1,
        sector: 1,
        user: 1,
        competition: 1,
        place: 1,
      },
    },
    {
      $sort: {
        kilogramms: -1,
      },
    },
    {
      $lookup: {
        from: "users", // must be the PHYSICAL name of the collection
        localField: "user",
        foreignField: "_id",
        as: "user",
      },
    },
    {
      $addFields: {
        user: {
          $arrayElemAt: ["$user", 0],
        },
      },
    },
    {
      $group: {
        _id: "$sector",
        res: {
          $push: "$$ROOT",
        },
      },
    },
  ]);

  res.status(200).json({ success: true, data });
});

和模式:

const mongoose = require('mongoose');

const ResultSchema = new mongoose.Schema({
  competitionSeries: {
    type: String,
    default: 0,
  },
  points: {
    type: Number,
    default: 0,
  },
  sector: {
    type: String,
  },
  kilogramms: {
    type: Number,
    default: 0,
  },
  place: {
    type: Number,
    default: 0,
  },
  isCompetitionRunning: {
    type: Boolean,
    default: true,
  },
  user: {
    type: mongoose.Schema.Types.ObjectId,
    ref: 'User',
    required: true,
  },
  team: {
    name: {
      type: mongoose.Schema.Types.ObjectId,
      ref: 'User',
    },
    partner: {
      type: String,
    },
    teamName: {
      type: String,
    },
  },

  competition: {
    type: mongoose.Schema.Types.ObjectId,
    ref: 'Competition',
    required: true,
  },
});

module.exports = Result = mongoose.model('Result', ResultSchema);

千克字段在MongoDB数据库中另存为Double 我在React的前端将值设置为数字。 我不确定是否导致问题。 公斤值应该是浮点数,例如14.5

这是正确的结果:

{
    "success": true,
    "data": [
        {
            "_id": "B",
            "res": [
                {
                    "_id": "5eca12e2607c2c0017c16904",
                    "points": 1,
                    "kilogramms": 90.52,
                    "place": 59,
                    "sector": "B",
                    "competition": "5eb90caa7b45620017a4d919",
                    "user": {
                        "_id": "5eb82c89e5d6cc0017e71a2a",
                        "avatar": "placeholder.jpg",
                        "role": "user"

                    }
                },
                {
                    "_id": "5eca1406607c2c0017c16918",
                    "points": 2,
                    "kilogramms": 39.45,
                    "place": 10,
                    "sector": "B",
                    "competition": "5eb90caa7b45620017a4d919",
                    "user": {
                        "_id": "5eb83175e5d6cc0017e71a42",
                        "avatar": "653571a228226499806e8a717cf2d6e1",
                        "role": "user"

                    }
                },
                {
                    "_id": "5eca11fc607c2c0017c168f5",
                    "points": 3,
                    "kilogramms": 29.62,
                    "place": 8,
                    "sector": "B",
                    "competition": "5eb90caa7b45620017a4d919",
                    "user": {
                        "_id": "5eb83970e5d6cc0017e71a64",
                        "avatar": "1589316331809-feederuser",
                        "role": "user"
                    }
                },
                {
                    "_id": "5eca1250607c2c0017c168fa",
                    "points": 4,
                    "kilogramms": 24.25,
                    "place": 56,
                    "sector": "B",
                    "competition": "5eb90caa7b45620017a4d919",
                    "user": {
                        "_id": "5eb83a00e5d6cc0017e71a67",
                        "avatar": "placeholder.jpg",
                        "role": "user"
                    }
                }

            ]
        },
        {
            "_id": "C",
            "res": [
                {
                    "_id": "5eca12cc607c2c0017c16903",
                    "points": 1,
                    "kilogramms": 72.43,
                    "place": 52,
                    "sector": "C",
                    "competition": "5eb90caa7b45620017a4d919",
                    "user": {
                        "_id": "5eb83c2ee5d6cc0017e71a70",
                        "avatar": "56065850e67a64878e5034d06cecc0ea",
                        "role": "user"
                    }
                },
                {
                    "_id": "5eca1307607c2c0017c16907",
                    "points": 2,
                    "kilogramms": 43.35,
                    "place": 12,
                    "sector": "C",
                    "competition": "5eb90caa7b45620017a4d919",
                    "user": {
                        "_id": "5eb998864d62090017231ce6",
                        "avatar": "placeholder.jpg",
                        "role": "user",
                        "name": "Halász Tibor"
                    }
                },
                {
                    "_id": "5eca1325607c2c0017c16909",
                    "points": 3,
                    "kilogramms": 39.43,
                    "place": 15,
                    "sector": "C",
                    "competition": "5eb90caa7b45620017a4d919",
                    "user": {
                        "_id": "5eb9b46c4d62090017231cf8",
                        "avatar": "placeholder.jpg",
                        "role": "user"
                    }
                },
                {
                    "_id": "5eca14c1607c2c0017c16927",
                    "points": 4,
                    "kilogramms": 36.99,
                    "place": 11,
                    "sector": "C",
                    "competition": "5eb90caa7b45620017a4d919",
                    "user": {
                        "_id": "5eb82fdbe5d6cc0017e71a3d",
                        "avatar": "placeholder.jpg",
                        "role": "user"
                    }
                }
            ]
        }
    ]
}

再次调用端点后,它显示了不同的顺序。意思是,C区排在第一位,这是不正确的,因为B区的公斤数更高。

1 个答案:

答案 0 :(得分:1)

您可以在文档中添加maxKilogramm字段,并通过在聚合末尾添加以下阶段来对该字段进行排序。

  {
    $addFields: {
      "maxKilogramm": {
        $max: "$res.kilogramms"
      }
    }
  },
  {
    $sort: {
      maxKilogramm: -1,
    },
  },
  {
    $project: {
      maxKilogramm: 0
    }
  }

Playground