如何正确制作多个字段$ min

时间:2018-06-06 00:58:42

标签: javascript mongodb meteor aggregation-framework

我有以下收藏:

{
  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" }}}
      } 

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

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

应该是:

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

如何使此查询有效?

1 个答案:

答案 0 :(得分:1)

问题

您获得错误价格的原因是因为您使用了两个单独的运算符(Comparator.<Optional<BigDecimal>,Boolean>comparing(Optional::isPresent) .reversed() //default ordering of booleans is false before true .thenComparing(o -> o.orElse(BigDecimal.ONE)) $min)并且它们彼此不同步。 $first返回整个集合中的最低价格,$min正在从整个集合中获取第一个文档。

<强>解决方案

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

$first