如何在TypeScript中实现MongoDB聚合管道的变量动态展开
问题解决方法
你需要的是在TypeScript代码层面将动态变量作为MongoDB查询的字段名,之前写法错误的原因是混淆了「JavaScript/TypeScript对象动态键语法」和「MongoDB聚合内部的字段引用语法」:$$xxx是MongoDB聚合的系统变量引用、$xxx是MongoDB聚合的文档字段引用,都不适用在代码层面构造动态对象键的场景。
正确写法
使用ES6+支持的计算属性名语法,直接将变量用方括号[]包裹作为对象的键即可。
对应第一段TypeScript代码修改后:
const pipeline = [ { $match: { [this.countryOriginFieldName!]: { $in: members }, // 用方括号包裹动态变量作为键 [keyToCheck]: { $nin: dictionaryNotAbsoluteFieldList } } }, // 后续聚合阶段... ]
对应补充的测试示例修改后(可直接运行得到预期结果):
// 动态字段变量 var keyToCheck = "indicator"; // 用计算属性构造查询条件,不需要额外加$或反引号 var queryMatch = { [keyToCheck]: "US$millions" } printjson(queryMatch); db.getCollection("temp_collection").aggregate([ { $match: queryMatch }, {$project: {indicator: 1, value: 1}} ]); // 测试数据插入 db.getCollection("temp_collection").insertMany([ { "indicator" : "US$millions", "value" : 1.0 }, { "indicator" : "US$millions", "value" : 2.0 }, { "indicator" : "EUROmillions", "value" : 3 } ]);
运行上述代码后会返回预期的两条indicator为US$millions的结果。
TypeScript类型报错处理
如果出现编译类型错误,可以通过类型断言规避:
import type { AggregatePipeline, Filter } from 'mongodb' const pipeline: AggregatePipeline<YourDocumentType> = [ { $match: { [this.countryOriginFieldName!]: { $in: members }, [keyToCheck]: { $nin: dictionaryNotAbsoluteFieldList } } as unknown as Filter<YourDocumentType> } ]
内容的提问来源于stack exchange,提问作者user1
相关产品推荐
相关产品推荐

