文档数据库 | Mongoerror:不支持聚合阶段:'$lookup 多个连接条件和不相关的子查询

raj*_*kar 5 mongodb mongodb-query aggregation-framework

我是 DocumentDB 的新手。尝试连接两个集合并执行查询、排序和投影等过滤器。

我有两个集合,需要对两个集合执行过滤器,结果应该是一个嵌入列表(其中应包含项目和子项目)。

第一个集合将在 Subitems 字段中保存第二个集合的 id。

这是第一个集合(项目):

{
    "_id": 897979789,
    "Country": "India",
    "State": "XXX",
    "Subitems": [ ObjectId("44497979789"), ObjectId("333897979789") ]
},
{
    "_id": 987979798,
    "Country": "Australia",
    "State": "YYY",
    "Subitems": [ ObjectId("97979789444"), ObjectId("897979789333") ]
}
Run Code Online (Sandbox Code Playgroud)

这是第二个集合:

{
"_id": 44497979789,
"EmployeeName": "Krishna",
"Occupation": "Engineer",
"ProjectsHandled": [
    {
        "ProjectName": "Project1"
    }
]
},
{
    "_id": 333897979789,
    "EmployeeName": "krish",
    "Occupation": "CTO",
    "ProjectsHandled": [
        {
            "ProjectName": "Project1"
        }
    ]
},
{
    "_id": 97979789444,
    "EmployeeName": "name",
    "Occupation": "CEO",
    "ProjectsHandled": [
        {
            "ProjectName": "Project2"
        }
    ]
},
{
    "_id": 897979789333,
    "EmployeeName": "name1",
    "Occupation": "manager",
    "ProjectsHandled": [
        {
            "ProjectName": "Project3"
        }
    ]
}
Run Code Online (Sandbox Code Playgroud)

这是我的查询:

let subItemPipeline: any[] = [{ $match: config.subItemsQuery }];
        if(Object.keys(config.subItemsSort || {}).length)
            subItemPipeline.push({$sort: config.subItemsSort});
        if(Object.keys(config.subItemsProjection || {}).length)
            subItemPipeline.push({$project: config.subItemsProjection});
            
        let query: any[] = [
            { 
                $match: config.itemsQuery
            },
            {
                $lookup: {
                    from: "Subitems",
                    pipeline: subItemPipeline,
                    as: "Subitems"
                }
            }
        ];

        if(Object.keys(config.overallQuery || {}).length) query.push({$match: config.overallQuery});
        if(Object.keys(config.itemsSort || {}).length) query.push({$sort: config.itemsSort});
        if(Object.keys(config.itemsProjection || {}).length) query.push({$project: config.itemsProjection});

        const items = await collection.aggregate(query).toArray();
Run Code Online (Sandbox Code Playgroud)

它在 MongoDB 中工作正常,但在 DocumentDB 中面临以下错误:

Mongoerror: aggregation stage not supported: '$lookup on multiple join conditions and uncorrelated subquery
Run Code Online (Sandbox Code Playgroud)

任何帮助将不胜感激

Tom*_*ert 3

来自 DocumentDB文档

Amazon DocumentDB 支持进行相等匹配(例如,左外连接)的功能,但不支持不相关的子查询。

Mongo文档特别提到了这一点:

相等匹配具有以下语法:

{
   $lookup:
     {
       from: <collection to join>,
       localField: <field from the input documents>,
       foreignField: <field from the documents of the "from" collection>,
       as: <output array field>
     }
}
Run Code Online (Sandbox Code Playgroud)

这是$lookupDocumentDB 支持的语法,您尝试使用的语法是$lookup版本 3.6 中添加的“新”语法,即他们所谓的“不相关子查询”,不幸的是,DocumentDB 目前还不支持它。

最简单的“快速”解决方案是向所有Subitems文档添加一个具有默认值的新字段。这将允许您使用equality match查找。

Subitems--- 编辑 --- 我建议您添加到新字段中的每个文档。

Subitems.updateMany(
    {
        
    },
    {
        $set: {
            n: 1
        }
    }
)
Run Code Online (Sandbox Code Playgroud)

对于您员工的收藏也是如此:

employee.updateMany(
    {
        
    },
    {
        $set: {
            n: 1
        }
    }
)
Run Code Online (Sandbox Code Playgroud)

现在您可以使用equality查找语法:

{
    $lookup: {
        from: 'Subitems',
        localField: 'n',
        foreignField: 'n',
        as: 'Subitems',
    },
}
... continue to filter sub items.
Run Code Online (Sandbox Code Playgroud)

请注意,这是一个玩具示例,它会在您过滤之前查找整个子项集合。

如果您确实想要一个良好的可扩展解决方案,您只需将其分成两个不同的调用即可。