我试图从两个模式返回数据。其中一个包含'球员'的信息,另一个包含每个'球员'的比赛'得分'的信息。
这是我的'播放器'模式:
import { Schema, model, models } from "mongoose";
const PlayerSchema = new Schema({
creator: {
type: Schema.Types.ObjectId,
ref: 'User',
},
name: {
type: String,
require: [ true, 'Name is required!' ],
},
email: {
type: String,
unique: [ true, 'Email already exist!' ],
required: [ true, 'Email is required!' ],
}
});
const Player = models.Player || model( 'Player', PlayerSchema );
export default Player;
字符串
**这是我的'Score'架构:(注意这一个还包含子文档内容)
import { Schema, model, models } from "mongoose";
const scoresToSave = new Schema({
player: {
type: Schema.Types.ObjectId,
ref: 'Player',
},
score: { type: Number }
});
const ScoreSchema = new Schema({
creator: {
type: Schema.Types.ObjectId,
ref: 'User',
},
tournament: {
type: Schema.Types.ObjectId,
ref: 'Tournament',
},
date: {
type: Date,
require: [ true, 'Date is required!' ],
},
scores: [scoresToSave],
});
const Score = models.Score || model( 'Score', ScoreSchema );
export default Score;
型
这是保存在收藏中的实际文档的示例。
玩家:
{
"_id":{"$oid":"652f3470729e8d8a59b221dd"},
"creator":{"$oid":"652af415729e8d8a59b2202f"},
"name":"Player 1",
"email":"[email protected]"
}
{
"_id":{"$oid":"652f36c9f6ad40c3aedf0cdf"},
"creator":{"$oid":"652af415729e8d8a59b2202f"},
"name":"Player 2",
"email":"[email protected]"
}
型
分数
{
"_id":{"$oid":"65386103b5e6b094e0980f2a"},
"creator":{"$oid":"652af415729e8d8a59b2202f"},
"tournament":{"$oid":"652f2515729e8d8a59b221b6"},
"date":{"$date":{"$numberLong":"1698192000000"}},
"scores":[
{
"player":{"$oid":"652f3470729e8d8a59b221dd"},
"score":{"$numberInt":"10"},
"_id":{"$oid":"65386103b5e6b094e0980f2b"}
},
{
"player":{"$oid":"652f36c9f6ad40c3aedf0cdf"},
"score":{"$numberInt":"20"},
"_id":{"$oid":"65386103b5e6b094e0980f2c"}
}
]
}
{
"_id":{"$oid":"6538611bb5e6b094e0980f59"},
"creator":{"$oid":"652af415729e8d8a59b2202f"},
"tournament":{"$oid":"652f2515729e8d8a59b221b6"},
"date":{"$date":{"$numberLong":"1698192000000"}},
"scores":[
{
"player":{"$oid":"652f3470729e8d8a59b221dd"},
"score":{"$numberInt":"11"},
"_id":{"$oid":"6538611bb5e6b094e0980f5a"}
},
{
"player":{"$oid":"652f36c9f6ad40c3aedf0cdf"},
"score":{"$numberInt":"21"},
"_id":{"$oid":"6538611bb5e6b094e0980f5b"}
}
]
}
型
这是我想创建的响应数据结构:
[
{
_id: new ObjectId("652f3470729e8d8a59b221dd"),
name: 'Player 1',
email: '[email protected]',
totalScore: 21
},
{
_id: new ObjectId("6536f85cb5e6b094e09809f1"),
name: 'Player 2',
email: '[email protected]',
totalScore: 41
},
]
型
我尝试获取该数据结构的实际代码是:
import { connectToDB } from "@utils/database";
import Player from "@models/player";
export const GET = async ( req ) => {
const resources = {
"_id": "$_id",
name: { "$first": "$name" },
email: { "$first": "$email" },
"totalScore": { "$sum": "scores.scores.score" },
};
try {
await connectToDB();
const players = await Player.aggregate([
{
$group: resources
}, {
$lookup: {
from: "Scores",
localField: "_id",
foreignField: "scores.player",
as: "score"
}
}
]);
console.log('TRY: ', players);
return new Response(
JSON.stringify(players),
{status: 200}
);
} catch (error) {
return new Response(
"Failed to fetch all players",
{status: 500}
);
}
}
型
以下是console.log('TRY: ', players);
返回的内容:
TRY: [
{
_id: new ObjectId("652f3470729e8d8a59b221dd"),
name: 'Player 1',
email: '[email protected]',
totalScore: 0,
score: []
},
{
_id: new ObjectId("6536f85cb5e6b094e09809f1"),
name: 'Player 2',
email: '[email protected]',
totalScore: 0,
score: []
},
]
型
有没有人能帮我理解我错过了什么?
谢谢你,谢谢
1条答案
按热度按时间vecaoik11#
我认为在
scores
集合上执行aggregate
会更容易。因为scores.score
字段位于该集合上,所以可以在该集合上执行$sum
。可能有更有效的方法,但此查询应该返回您想要的结果:字符串
请参阅HERE以获取工作示例。
说明:
$unwind
:扁平化scores
数组,这样我们每个scores文档得到一个对象。这显然会重复文档,但更容易按玩家分组。$group
:按玩家对每个对象进行分组,$sum
为它们的分数。$lookup
:现在加入基于_id
的players
集合。但是因为$lookup
返回一个数组,所以只需分配给一个名为fromPlayers
的新字段。$replaceRoot
:通过将fromPlayers
数组与上一个管道阶段的原始文档合并,创建一个新的根文档。$project
:现在从输出中删除fromPlayers
数组和creator
字段。