【问题标题】:How to make multiple fields $min properly [duplicate]如何正确制作多个字段$ min [重复]
【发布时间】:2018-06-06 11:40:39
【问题描述】:

我有以下收藏:

{
  TariffId: 0101H01,
  RoomId: 01H01,
  HotelId: H01,
  Price: 180,
  ...       //other fields
},
{
  TariffId: 0201H01,
  RoomId: 01H01,
  HotelId: H01,
  Price: 120
}
{ 
  TariffId: 0301H01,
  RoomId: 02H01,
  HotelId: H01,
  Price: 100
  ...       //other fields
}

我想为每个 HotelId 输出最低价格,并确切知道它与哪个 RoomId 和 TariffId 以及所有其他字段相关。结果应该是:

{ 
  TariffId: 0201H01,
  RoomId: 01H01,
  HotelId: H01,
  Price: 120
}
{ 
  TariffId: 0301H01,
  RoomId: 02H01,
  HotelId: H01,
  Price: 100
  ...       //other fields
}

我试过了:

 db.collection.aggregate{
      {$group: {_id :{ RoomId: "$RoomId", tariffId: "$_id"} , HotelId:{$first: "$HotelId"} , Price: {$min: "$Price" }}},
      {$group: {_id : "$HotelId", RoomId: {$first:"$RoomId"}, tariffId: {$first: "$_id"} , Price: {$min: "$Price" }}}
      } 

但是结果不正确。第一个错误地将关税Idm0101H01 分配给最低价格:120。这是我得到的:

{ 
  TariffId: 0101H01,
  RoomId: 01H01,
  HotelId: H01,
  Price: 100
  ...       //other fields
}

它应该是:

{ 
  TariffId: 0301H01,
  RoomId: 02H01,
  HotelId: H01,
  Price: 100
  ...       //other fields
}

如何使这个查询有效?

【问题讨论】:

    标签: javascript mongodb meteor aggregation-framework


    【解决方案1】:

    问题

    您得到错误价格的原因是因为您使用了两个单独的运算符($min$first)并且它们彼此不同步。 $min 正在返回整个集合中的最低价格,$first 正在获取整个集合中的第一个文档。

    解决方案

    您要做的是排序(确保有索引),然后分组并使用$first 运算符。由于我们在分组之前进行排序,因此第一个文档将是具有最低价格的文档。

    db.collection.aggregate([
        // important sort by price before grouping
        {
            $sort: { Price: 1 }
        },
        // group by hotel and room ID and get the first document
        {
            $group: {
                _id: {                
                    HotelId: '$HotelId',
                    RoomId: "$RoomId",
                },
                doc: { $first: '$$ROOT' }
            }
        },
        // (optional) replace the root document
        {
            $replaceRoot: { newRoot: '$doc' }
        }
    ])
    

    【讨论】:

    • 谢谢@leonziyo!它很有魅力!在这种情况下不使用 $min 并且仍然通过排序和获得 $first 答案来获得最小值是非常聪明的。我只需要从分组中取出 RoomId,它就会找到每个酒店的最小值。因为我有一个 Mongodb
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-05
    • 2017-02-18
    相关资源
    最近更新 更多