Mongo "Error in $cursor stage..." 在聚合管道中

Mongo "Error in $cursor stage..." in aggregate pipeline

我有collection订单

{_id: ObjectId("5e32d0fadf54cb3d81293fb3"),
user_id:'test_user',
product_id:'product_2_id'
created_at:'2020-02-25T07:04:05.439+00:00'
}

我需要加入 collection recommendedProducts 并把 orders.user_id 作为通用键recommendedProducts.userId 看起来像

{_id: ObjectId("5e3ac145df54cbeca6230924"),
userId:'test_user'
rankedList:[
0:{Name:'Product_4',id:'product_4_id'},
1:{Name:'Product_1',id:'product_1_id'},
2:{Name:'Product_2',id:'product_2_id'}],
Date:'2020-02-25T06:03:55.439+00:00'
}

{_id: ObjectId("5e388da4df54cb8efb47e61b"),
userId:'test_user'
rankedList:[
0:{Name:'Product_5',id:'product_5_id'},
1:{Name:'Product_6',id:'product_6_id'},
2:{Name:'Product_3',id:'product_3_id'}],
Date:'2020-02-25T05:03:55.439+00:00'
}

我已阅读 this and also and 篇文章,但我仍然无法理清应该如何正确编写聚合管道。到目前为止,我有以下

db.orders.aggregate([
 {
    $lookup: {
        "from": "recommendedProducts",
        "as": "recommendations",
        "let": {
            "id": "$user_id"
        },
        "pipeline": [{
                "$match": {
                    "$expr": {
                        "$eq": ["$userId", "$$id"]
                    }
                }
            },
            {
                "$sort": {
                    "Date": -1
                }
            },
            {
                "$limit": 1
            }
        ]
    }
}
])

这应该可以正常工作但没有成功。 我需要保留在这里的是来自 collection 推荐产品的最后一个文档,并且只有一个文档来自那里,这就是为什么我也使用排序和限制但我得到错误 "$cursor 中的错误stage :: :: operation exceeded time limit 这里哪里出错了?

当使用采用 letpipeline$lookup 形式时,以及当使用 $expr 时,查询规划器目前无法有效地使用一个索引。

这意味着对于每个订单,查找阶段正在扫描整个 recommendedProducts 集合以查找匹配的文档。

如果您要使用其他形式的查找,并且在 recommendedProducts 集合中的 userId 字段上有一个索引,则可以使用该索引更快地找到匹配的产品,并且您然后可以使用 unwind、sort 和 group,或者只是 reduce 来获取最新的值。

db.orders.aggregate([
 {
    $lookup: {
        "from": "recommendedProducts",
        "as": "recommendations",
        "localField": "user_id",
        "foreignField": "userId"
 },
 {$addFields: {
   recommendations:{ 
        $reduce: {
            input: "$recommendations",
            initialValue: {$arrayElemAt:["$recommendations",0]},
            in: {
               $cond: {
                    if: {$gt:["$$this.Date","$$value.Date"]},
                    then: "$$this",
                    else: "$$value"
                }
            }
        }
   }
 }}
])