MongoDB聚合报错:$arrayElemAt的第一个参数必须是数组
解决MongoDB聚合中$addFields报错的问题
嘿,我一眼就看出问题出在哪了——你在聚合管道里的阶段顺序搞反啦!
错误原因分析
在你的Stage 3($project)阶段,你只保留了Enterprise这个字段,其他所有字段(包括joined)都被默认排除了。等到Stage 4执行$addFields的时候,$joined已经不存在了,自然没法作为$arrayElemAt的数组参数,这就是你看到错误"$arrayElemAt's first argument must be an array"的原因。
解决方案1:调整阶段顺序,先添加字段再投影
把$addFields移到$project前面,这样joined字段还存在,就能正常提取数据:
db.getCollection("ConnectionEntity").aggregate([ // Stage 1: 匹配目标记录 { $match: { "Id":"9c06cb0c-966a-4f6b-b087-816587629079" } }, // Stage 2: 关联Enterprise集合 { $lookup: { from: "Enterprise", localField: "EnterpriseId", foreignField: "_id", as: "joined" } }, // Stage 3: 先添加Enterprise.Id字段(此时joined还存在) { $addFields: { "Enterprise.Id": {"$arrayElemAt": ["$joined._id", 0]} } }, // Stage 4: 再投影出需要的字段 { $project: { "Enterprise": 1 } }, ]);
解决方案2:在$project中直接构造完整的Enterprise对象
其实你完全可以把两个字段的提取合并到同一个$project阶段,这样更简洁:
db.getCollection("ConnectionEntity").aggregate([ { $match: { "Id":"9c06cb0c-966a-4f6b-b087-816587629079" } }, { $lookup: { from: "Enterprise", localField: "EnterpriseId", foreignField: "_id", as: "joined" } }, { $project: { "Enterprise": { "Profile": {"$arrayElemAt": ["$joined.Profile", 0]}, "Id": {"$arrayElemAt": ["$joined._id", 0]} } } }, ]);
补充说明
$lookup返回的是一个数组(即使只匹配到一条记录),所以用$arrayElemAt提取第一个元素是正确的做法;- MongoDB的
$project默认会排除所有未显式指定的字段,如果你需要保留其他字段,记得在$project里加上(比如"_id": 1)。
内容的提问来源于stack exchange,提问作者TomSelleck
相关产品推荐
相关产品推荐

