MongoDB 使用关联的 collection 字段进行查找和排序的聚合正在减慢查询速度
MongoDB aggregate with lookup and sort using associated collection fields is slowing down the query
我的 mongodb 数据库中有两个 collection,如下所示:
employee_details with approximately 330000 documents which has department_id as a reference from departments collection
departments collections with 2 fields _id and dept_name
我已将索引添加到 collection 中,如下所示
db.departments.createIndex( { dept_name: 1 } )
db.employee_details.createIndex( { department_id: 1 } )
db.employee_details.createIndex( { employee_fname: 1 } )
我想通过加入两个 collection 来获取数据以在数据 table 上列出。但是当我尝试这样做时,我遇到了两个问题。
首先,当我在查找后添加排序时,查询 运行 需要很长时间,我添加了查找后排序,因为我需要对 collection 个部门的 dept_name 进行排序。查询如下
db.getCollection("employee_details").aggregate([
{
$lookup: {
from: "departments",
localField: "department_id",
foreignField: "_id",
as: "Department"
}
},
{ $unwind: { path: "$Department", preserveNullAndEmptyArrays: true } },
{ $sort: { "Department.dept_name": 1 } },
{ $limit: 30 }
]);
其次,当我在查找上方添加排序时,查询变得很快,但如果我使用 dept_name 或 department_id 进行排序,结果会给出错误的排序(排序对 [=15= 的字段工作正常] collection)。查询如下
db.getCollection("employee_details").aggregate([
{ $unwind: { path: "$Department", preserveNullAndEmptyArrays: true } },
{ $sort: { "Department.dept_name": 1 } },
//{ $sort: { "department_id": 1 } }, // tried this also
{ $limit: 30 },
{
$lookup: {
from: "departments",
localField: "department_id",
foreignField: "_id",
as: "Department"
}
}
]);
有人可以提供优化的解决方案来获取数据以及从所有相关的 collection 中排序。
提前谢谢你。
试试这个:
db.departments.aggregate([
{
$sort: {
"dept_name": 1
}
},
{
$lookup: {
from: "employee_details",
localField: "_id",
foreignField: "department_id",
as: "Employee"
}
},
{
$unwind: "$Employee"
},
{
$addFields: {
tmp: {
$mergeObjects: [
{
Department: "$$ROOT"
},
"$Employee"
]
}
}
},
{
$project: {
"tmp.Department.Employee": 0
}
},
{
$addFields: {
"tmp.Department": [
"$tmp.Department"
]
}
},
{
$replaceRoot: {
newRoot: "$tmp"
}
},
{
$limit: 30
}
])
您可以使用以下聚合:
db.getCollection("departments").aggregate([
{
$sort: {
"dept_name": 1
}
},
{
$lookup: {
from: "employee_details",
localField: "_id",
foreignField: "department_id",
as: "employees"
}
},
{
$unwind: "$employees"
},
{
$limit: 30
},
{ $addFields: { "employees.department_name": "$dept_name" } },
{ $replaceRoot: { newRoot: "$employees" } }
])
这适用于 MongoDB 3.4 版,即使没有任何索引也足够快。
我的 mongodb 数据库中有两个 collection,如下所示:
employee_details with approximately 330000 documents which has department_id as a reference from departments collection
departments collections with 2 fields _id and dept_name
我已将索引添加到 collection 中,如下所示
db.departments.createIndex( { dept_name: 1 } )
db.employee_details.createIndex( { department_id: 1 } )
db.employee_details.createIndex( { employee_fname: 1 } )
我想通过加入两个 collection 来获取数据以在数据 table 上列出。但是当我尝试这样做时,我遇到了两个问题。
首先,当我在查找后添加排序时,查询 运行 需要很长时间,我添加了查找后排序,因为我需要对 collection 个部门的 dept_name 进行排序。查询如下
db.getCollection("employee_details").aggregate([
{
$lookup: {
from: "departments",
localField: "department_id",
foreignField: "_id",
as: "Department"
}
},
{ $unwind: { path: "$Department", preserveNullAndEmptyArrays: true } },
{ $sort: { "Department.dept_name": 1 } },
{ $limit: 30 }
]);
其次,当我在查找上方添加排序时,查询变得很快,但如果我使用 dept_name 或 department_id 进行排序,结果会给出错误的排序(排序对 [=15= 的字段工作正常] collection)。查询如下
db.getCollection("employee_details").aggregate([
{ $unwind: { path: "$Department", preserveNullAndEmptyArrays: true } },
{ $sort: { "Department.dept_name": 1 } },
//{ $sort: { "department_id": 1 } }, // tried this also
{ $limit: 30 },
{
$lookup: {
from: "departments",
localField: "department_id",
foreignField: "_id",
as: "Department"
}
}
]);
有人可以提供优化的解决方案来获取数据以及从所有相关的 collection 中排序。 提前谢谢你。
试试这个:
db.departments.aggregate([
{
$sort: {
"dept_name": 1
}
},
{
$lookup: {
from: "employee_details",
localField: "_id",
foreignField: "department_id",
as: "Employee"
}
},
{
$unwind: "$Employee"
},
{
$addFields: {
tmp: {
$mergeObjects: [
{
Department: "$$ROOT"
},
"$Employee"
]
}
}
},
{
$project: {
"tmp.Department.Employee": 0
}
},
{
$addFields: {
"tmp.Department": [
"$tmp.Department"
]
}
},
{
$replaceRoot: {
newRoot: "$tmp"
}
},
{
$limit: 30
}
])
您可以使用以下聚合:
db.getCollection("departments").aggregate([
{
$sort: {
"dept_name": 1
}
},
{
$lookup: {
from: "employee_details",
localField: "_id",
foreignField: "department_id",
as: "employees"
}
},
{
$unwind: "$employees"
},
{
$limit: 30
},
{ $addFields: { "employees.department_name": "$dept_name" } },
{ $replaceRoot: { newRoot: "$employees" } }
])
这适用于 MongoDB 3.4 版,即使没有任何索引也足够快。