MongoDB聚合框架中如何用字段值作为键访问字段属性?
实现动态获取嵌套字段的MongoDB聚合方案
你尝试的$symbolInfo.$mainSymbol.rate写法无法生效,因为MongoDB的点符号语法不支持直接用字段值作为嵌套键名来访问。要实现根据mainSymbol的值动态获取对应rate的需求,可以用以下两种方案:
方案一:使用$getField(MongoDB 5.0+ 版本适用)
MongoDB 5.0新增的$getField操作符支持动态指定要访问的字段名,写法简洁直接:
db.symbol_rates.aggregate([ { $addFields: { mainSymbolRate: { $getField: { field: "rate", input: { $getField: { field: "$mainSymbol", input: "$symbolInfo" } } } } } } ])
也可以拆分成两步$addFields,逻辑更清晰:
db.symbol_rates.aggregate([ { $addFields: { // 先取出mainSymbol对应的symbolInfo子文档 tempSymbolDoc: { $getField: { field: "$mainSymbol", input: "$symbolInfo" } } } }, { $addFields: { mainSymbolRate: "$tempSymbolDoc.rate", tempSymbolDoc: "$$REMOVE" // 删除临时字段 } } ])
方案二:兼容旧版本(MongoDB 4.4及以下)
对于不支持$getField的旧版本,可通过$objectToArray将嵌套对象转为键值对数组,再筛选匹配:
db.symbol_rates.aggregate([ { $addFields: { // 将symbolInfo转为[{k: "USD", v: {rate:4.03}}, ...]格式的数组 symbolInfoArray: { $objectToArray: "$symbolInfo" } } }, { $addFields: { // 筛选出k等于mainSymbol的数组项 targetEntry: { $arrayElemAt: [ { $filter: { input: "$symbolInfoArray", cond: { $eq: ["$$this.k", "$mainSymbol"] } } }, 0 // 取筛选结果的第一个元素(确保唯一匹配) ] } } }, { $addFields: { mainSymbolRate: "$targetEntry.v.rate", // 清理临时字段 symbolInfoArray: "$$REMOVE", targetEntry: "$$REMOVE" } } ])
两种方案执行后,都能得到你期望的输出结果:
{ "mainSymbol": "USD", "mainSymbolRate": 4.03, "symbolInfo": { "USD": { "rate": 4.03 }, "GBP" : { "rate": 3.21 } } }
内容的提问来源于stack exchange,提问作者trajan
相关产品推荐
相关产品推荐

