Ste*_*fel 6 mongodb mongodb-query aggregation-framework
假设我有两个收藏,任务和客户.
客户通过客户中的"customerId"字段与任务建立1:n的关系.
我现在有一个视图,我需要显示客户名称的任务.我还需要能够过滤和排序客户名称.这意味着我无法在以下查询中的$ lookup之前执行$ limit或$ match阶段.
所以这是我的示例查询:
db.task.aggregate([
{
"$match": {
"_deleted": false
}
},
"$lookup": {
"from": "customer",
"let": {
"foreignId": "$customerId"
},
"pipeline": [
{
"$match": {
"$expr": {
"$and": [
{
"$eq": [
"$_id",
"$$foreignId"
]
},
{
"$eq": [
"$_deleted",
false
]
}
]
}
}
}
],
"as": "customer"
},
{
"$unwind": {
"path": "$customer",
"preserveNullAndEmptyArrays": true
}
},
{
"$match": {
"customer.name": 'some_search_string'
}
},
{
"$sort": {
"customer.name": -1
}
},
{
"$limit": 35
},
{
"$project": {
"_id": 1,
"customer._id": 1,
"customer.name": 1,
"description": 1,
"end": 1,
"start": 1,
"title": 1
}
}
])
Run Code Online (Sandbox Code Playgroud)
当集合的大小增加时,此查询变得非常慢.拥有1000个任务和20个客户,已经需要大约500毫秒来交付结果.
我知道,这是因为$ lookup运算符必须为进入聚合管道查找阶段的每一行执行表扫描.
我试图设置如下所述的索引:查找聚合性能差,但似乎没有任何影响.
我的下一个猜测是$ lookup阶段的"sub"-pipeline无法使用索引,所以我用一个简单的替换它
"$lookup": {
"from": "customer",
"localField": "customerId",
"foreignField": "_id",
"as": "customer"
}
Run Code Online (Sandbox Code Playgroud)
但仍然没有使用索引或对性能没有任何影响.(说实话,我不知道两者都是这种情况,因为.explain()不能用于聚合管道.)
我尝试了以下索引:
我很感激任何关于我做错了什么的想法,或者我如何通过更好的聚合管道实现同样的目标.
附加信息:我正在使用三个成员的副本集.我在使用MongoDB 4.0.
请注意:我知道我正在使用非关系型数据库来实现高度关系目标,但在这个项目中,MongoDB是我们的选择,因为它具有ChangeStream功能.如果有人知道具有类似功能的不同数据库(更改的实时推送通知),这可以在内部运行(因此Firebase退出),我很乐意听到它!
提前致谢!
| 归档时间: |
|
| 查看次数: |
513 次 |
| 最近记录: |