我有以下收藏:
{
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
}
如何使此查询有效?
答案 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