在mongodb中添加复杂条件的新字段

问题描述 投票:0回答:1

在我的拍卖应用程序中,我有 3 个主表:拍卖、出价和用户。我正在尝试构建一个 MongoDB 查询,在其中我可以获得每个用户在每次拍卖中的最高出价(如果他们出价),我还希望有一个列来说明该特定拍卖中用户的状态。我可以获得除状态列之外的所有列,这有点复杂。

状态栏逻辑

  1. 如果拍卖尚未结束:
    1. 如果用户是最高出价者,则“您是最高出价者”。
    2. 如果用户不是最高出价者,则“您的出价已被超过”。
  2. 如果拍卖已结束:
    1. 如果用户是最高出价者,则“您赢得了拍卖”。
    2. 如果用户不是最高出价者,则“您输掉了拍卖”。

在我的拍卖应用程序中,我有 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
                }
            }
        ]);

任何帮助将不胜感激!

node.js mongodb mongoose mongodb-query aggregation-framework
1个回答
0
投票

一个选项是:

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
    }
  }
])
© www.soinside.com 2019 - 2024. All rights reserved.