mongodb聚合,根据查找结果排序

时间:2018-08-07 10:04:17

标签: mongodb sorting aggregation-framework

假设我具有以下数据架构(我只报告了几个字段)

托收单

| id    | service | customer |
|-------|---------|----------|
| O001  | SRV001  | CST001   |
| O002  | SRV001  | CST001   |
| O003  | SRV001  | CST002   |
| O004  | SRV002  | CST003   |
| O005  | SRV002  | CST002   |
| O006  | SRV003  | CST004   |

托收客户

| id     | name    | city     |
|--------|---------|----------|
| CST001 | Paul    | New York |
| CST002 | Anna    | London   |
| CST003 | John    | Milan    |
| CST004 | Julia   | Paris    |

假设我要按客户姓名对订单进行排序

这个想法是使用带有$ lookup的聚合来加入客户来订购和排序结果

db.order.aggregate([
   { $lookup: { 'foreignField': 'id', 
                'as': '__customer', 
                'from': 'customer', 
                'localField':'customer'} },
   { $unwind: '$__customer'},
   { $sort:   { '__customer.name': 1 } }
])

如果数据有限,此方法可以正常工作。如果您有大量数据,则该数据将不起作用,因为排序是在$ lookup结果上执行的,因此即使客户集合中的“名称”字段具有索引,mongodb也没有索引可使用。

我认为没有办法实现这一目标。

有人可以确认吗?

1 个答案:

答案 0 :(得分:0)

Documentation说:

  

$ match和$ sort管道运算符出现在管道的开始处时可以利用索引。

更多:

  

在3.2版中进行了更改:从MongoDB 3.2开始,索引可以覆盖聚合管道。在MongoDB 2.6和3.0中,索引无法覆盖聚合管道,因为即使管道使用索引,聚合仍需要访问实际文档。

据此,MongoDB(3.2及更高版本)聚合使用索引。

但是,您的管道有一些技巧。例如,您可以聚合customer表,而不是order表。对其进行排序,然后为lookuporders

或者您可以group之前customer,然后执行lookup。我不认为它会运行得更快(实际上我认为它会更慢),但是您可以尝试一下。

请不要忘记使用matcheslimits-它们可以加快聚合速度。即使在大型管道中,您通常也可以match更接近开始,但有时您仍然需要考虑清楚。