在我的拍卖应用程序中,我有 3 个主表:拍卖、出价和用户。我正在尝试构建一个 MongoDB 查询,在其中我可以获得每个用户在每次拍卖中的最高出价(如果他们出价),我还希望有一个列来说明该特定拍卖中用户的状态。我可以获得除状态列之外的所有列,这有点复杂。
状态栏逻辑
在我的拍卖应用程序中,我有 3 个主表:拍卖、出价和用户。表结构如下所示
用户
用户ID | 全名 | 角色 |
---|---|---|
用户1 | xxxx | 投标人 |
用户2 | xxxx | 投标人 |
用户3 | xxxx | 投标人 |
拍卖
拍卖ID | 开始日期 | 结束日期 | 起价 |
---|---|---|---|
10001 | 2023-09-20T12:37:00Z | 2023-09-21T12:37:00Z | 100 |
10002 | 2023-09-22T12:37:00Z | 2023-09-22T12:37:00Z | 2000 |
10003 | 2023-09-22T12:37:00Z | 2023-09-25T12:37:00Z | 800 |
10004 | 2023-09-22T12:37:00Z | 2023-09-26T12:37:00Z | 3000 |
出价
出价ID | 拍卖ID | 投标人ID | 出价金额 | 出价日期 |
---|---|---|---|---|
101 | 10001 | 用户1 | 120 | 2023-09-20T13:33:44Z |
102 | 10001 | 用户2 | 140 | 2023-09-20T13:33:44Z |
103 | 10001 | 用户1 | 160 | 2023-09-20T13:33:44Z |
104 | 10001 | 用户2 | 200 | 2023-09-20T13:33:44Z |
105 | 10001 | 用户1 | 240 | 2023-09-20T13:33:44Z |
106 | 10002 | 用户3 | 2200 | 2023-09-20T13:33:44Z |
107 | 10002 | 用户2 | 2400 | 2023-09-20T13:33:44Z |
108 | 10002 | 用户1 | 2800 | 2023-09-20T13:33:44Z |
109 | 10002 | 用户2 | 3200 | 2023-09-20T13:33:44Z |
110 | 10002 | 用户3 | 3400 | 2023-09-20T13:33:44Z |
111 | 10003 | 用户1 | 900 | 2023-09-20T13:33:44Z |
112 | 10003 | 用户2 | 1200 | 2023-09-20T13:33:44Z |
113 | 10003 | 用户3 | 1600 | 2023-09-20T13:33:44Z |
114 | 10003 | 用户2 | 1800 | 2023-09-20T13:33:44Z |
预期结果
用户ID | 拍卖ID | 最大出价金额 | 状态 |
---|---|---|---|
用户1 | 1001 | 240 | 您赢得了拍卖 |
用户1 | 1002 | 2800 | 你输掉了拍卖 |
用户1 | 1003 | 900 | 您的出价已被超过 |
用户2 | 1001 | 2 75e1 00 | 你输掉了拍卖 |
用户2 | 1002 | 3200 | 你输掉了拍卖 |
用户2 | 1003 | 1800 | 您是出价最高者 |
用户3 | 1002 | 3400 | 您赢得了拍卖 |
用户3 | 1003 | 1600 | 您的出价已被超过 |
这是我的 mongodb 查询,它在状态列中给出错误的结果
this.bidModel.aggregate([
{
$sort: {
auction: 1,
bidAmount: -1
}
},
{
$group: {
_id: {
bidder: "$bidder",
auction: "$auction"
},
highestBid: { $first: "$$ROOT" }
}
},
{ $lookup: { from: 'users', localField: '_id.bidder', foreignField: '_id', as: 'bidderInfo' } },
{ $lookup: { from: 'auctions', localField: '_id.auction', foreignField: '_id', as: 'auctionInfo' } },
{ $unwind: '$bidderInfo' },
{ $unwind: '$auctionInfo' },
{
$project: {
_id: 0, // Exclude the _id field
bidID: "$highestBid.bidID",
bidAmount: "$highestBid.bidAmount",
bidDate: "$highestBid.bidDate",
fullName: "$bidderInfo.fullName",
bidder: "$bidderInfo._id",
auctionID: "$auctionInfo._id",
auction: "$auctionInfo.title",
endDate: "$auctionInfo.endDate"
}
},
{
$addFields: {
status: {
$cond: [
{
$and: [
{ $eq: ["$bidder", "$_id.bidder"] }, // User is highest bidder
{ $gt: ["$endDate", new Date()] } // Auction has not ended
]
},
"You are the highest bidder",
{
$cond: [
{
$and: [
{ $ne: ["$bidder", "$_id.bidder"] }, // User is outbid
{ $gt: ["$endDate", new Date()] } // Auction has not ended
]
},
"You have been outbid",
{
$cond: [
{ $eq: ["$bidder", "$_id.bidder"] }, // User is highest bidder
"You won the auction",
"You lost the auction" // Auction ended, and user is not the highest bidder
]
}
]
}
]
}
}
},
// Sort the result by bidder
{
$sort: {
userID: 1 // Sort by bidder in ascending order
}
}
]);
任何帮助将不胜感激!
一个选项是:
db.bids.aggregate([
{
$group: {
_id: {
bidder: "$bidderID",
auction: "$auctionID"
},
myHighestBid: {
$max: "$bidAmount"
}
}
},
{
$lookup: {
from: "auctions",
localField: "_id.auction",
foreignField: "auctionID",
as: "isEnded",
pipeline: [
{
$match: {
$expr: {
$lt: [
"$endDate",
"$$NOW"
]
}
}
},
{
$project: {
_id: 1
}
}
]
}
},
{
$setWindowFields: {
partitionBy: "$_id.auction",
sortBy: {
myHighestBid: -1
},
output: {
maxBidAmount: {
$max: "$myHighestBid",
window: {
documents: [
"unbounded",
"current"
]
}
}
}
}
},
{
$set: {
isEnded: {
$eq: [
{
$size: "$isEnded"
},
1
]
}
}
},
{
$project: {
_id: 0,
userID: "$_id.bidder",
auctionID: "$_id.auction",
maxBidAmount: "$myHighestBid",
status: {
$switch: {
branches: [
{
case: {
$and: [
{
$eq: [
"$myHighestBid",
"$maxBidAmount"
]
},
"$isEnded"
]
},
then: "You won the auction"
},
{
case: {
$and: [
{
$eq: [
"$myHighestBid",
"$maxBidAmount"
]
},
{
$not: "$isEnded"
}
]
},
then: "You are the highest bidder"
},
{
case: {
$and: [
{
$lt: [
"$myHighestBid",
"$maxBidAmount"
]
},
"$isEnded"
]
},
then: "You lost the auction"
}
],
default: "You have been outbid"
}
}
}
},
{
$sort: {
userID: 1,
auctionID: 1
}
}
])