Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
mongodb聚合,基于查找结果排序_Mongodb_Sorting_Aggregation Framework - Fatal编程技术网

mongodb聚合,基于查找结果排序

mongodb聚合,基于查找结果排序,mongodb,sorting,aggregation-framework,Mongodb,Sorting,Aggregation Framework,假设我有以下数据架构(我只报告几个字段) 托收单 | id | service | customer | |-------|---------|----------| | O001 | SRV001 | CST001 | | O002 | SRV001 | CST001 | | O003 | SRV001 | CST002 | | O004 | SRV002 | CST003 | | O005 | SRV002 | CST002 | | O006

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

托收单

| 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没有要使用的索引,即使customer集合中的字段“name”有索引

我认为没有办法做到这一点

有人能证实吗?

说:

$match和$sort管道操作符可以在管道的开头使用索引

还有更多:

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

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

不过,您的管道有一些技巧。例如,您可以聚合
客户
表,而不是
订单
。对其排序,然后对订单执行
查找

或者您可以通过
客户
进行分组
,然后执行
查找
。我不认为它会更快(实际上我认为它会更慢),但你可以试着想想


不要忘记使用
匹配
限制
——它们加快了聚合速度。即使在大型管道中,您通常也可以在更接近开始的地方进行匹配,但有时您需要好好考虑。

聚合客户表不是一个选项,因为关系不是1到1。我需要一个通用解决方案一些过滤器(使用匹配实现)可能存在,但最坏的情况是它不存在。@lorenzo您不需要1对1关系<代码>查找
对于一个字段
id
使用
展开
会给你一对一的关系,但是当你按照
客户进行
排序
时,名称
你会得到
多个订单给一个客户
关系,这与排序
客户
查找
订单
(对于
订单
,没有
解除
)。您将获得一份客户列表(其中包含订单列表)。这里有一个常见情况-如果您只需要前20份订单,那么您可以限制(20)您的客户,然后
解除
订单,按客户排序(因为解除可以自行排序)和限制(20)再说一遍。@Lorenzo只是为了确保我们谈论同样的事情,这是我建议的管道:
db.customer.aggregate([{$sort:{'name':1},{$lookup:{'localField':''id','from':'order','as':'orders',},{$match:{$orders:{$gt:[]},{$limit 20},{$unwind:'$orders'},{$limit:20},]
谢谢,下周我会去看看。我这周不在家