简体   繁体   中英

Trying to get data from Mongo DB with aggregate

I have "Offers" and "Requests" collections, I need to get all offers that user made, group them by requests and find the lowest "Offer.price" on each request, each offer has requestId field. I am using aggregate to solve this,

 db.Offer.aggregate([{ $match: { ownerId: mongoose.Types.ObjectId(req.params.ownerId) } }, { $group: { _id: "$requestId", price: { $min: "$price" } } } ])

and This is what i get:

 [ { _id: 5dc47241af1406031489c65c, price: 14 }, { _id: 5dc47241af1406031489c653, price: 3 }, { _id: 5dc47241af1406031489c656, price: 5 }, { _id: 5dc8add63f73953ff408f962, price: 6 }, { _id: 5dc8add63f73953ff408f969, price: 22 }, { _id: 5dc47241af1406031489c658, price: 1 } ]

Now I want to populate these with rest of the data from "Offer"

 const OfferSchema = new Schema({ requestId: { type: Schema.Types.ObjectId, ref: 'Request' }, ownerId: { type: Schema.Types.ObjectId, required: true, ref: 'User' }, price: { type: Number, required: true }, createdAt: { type: Date, default: Date.now }, isBest: { type: Boolean, default: false }, isWinner: { type: Boolean, default: false, } });

What would be best way to do something like this? Thank you for your help!

Consider the following dataset:

db.dum.insert({ownerId:1, requestId:'a', price:3, createdAt:3, isWinner:true})
db.dum.insert({ownerId:1, requestId:'a', price:1, createdAt:1, isWinner:false})
db.dum.insert({ownerId:1, requestId:'a', price:2, createdAt:2, isWinner:true})
db.dum.insert({ownerId:1, requestId:'b', price:4, createdAt:2, isWinner:true})
db.dum.insert({ownerId:1, requestId:'b', price:5, createdAt:1, isWinner:false})
db.dum.insert({ownerId:2, requestId:'b', price:5, createdAt:1, isWinner:false})

You could use $reduce

Here, for a grouping id, we keep all matching documents as an array ( candidates ).

On the project stage, for each group we iterate through the array, and reduce it to the minimal element found (by price that is)

db.dum.aggregate([{
    $match: {
      ownerId: 1
    }
  },
  {
    $group: {
      _id: "$requestId",
      candidates: { $push:'$$ROOT'}
    }
  },
  {
    $project:{
      item: {
        $reduce: {
          input: '$candidates',
          initialValue: '$candidates.0',
          in: { 
            $cond: {
              if: {
                $lt: ['$$value.price', '$$this.price']
              },
              then:'$$value',
              else:'$$this'
            }
          }
        }
      }
    }
  },
  {
    $replaceRoot:{newRoot:'$item'}
  }
]).toArray()

output:

[
  {
    "_id" : ObjectId("5ddcc8e0eb1f0217802fb507"),
    "ownerId" : 1,
    "requestId" : "b",
    "price" : 4,
    "createdAt" : 2,
    "isWinner" : true
  },
  {
    "_id" : ObjectId("5ddcc8e0eb1f0217802fb505"),
    "ownerId" : 1,
    "requestId" : "a",
    "price" : 1,
    "createdAt" : 1,
    "isWinner" : false
  }
]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM