我需要更新所有现有的文档并加密敏感信息。我在代码中编写了一个脚本,如下所示,对每个文档中的“name”字段进行加密:
const update = await User.updateMany(
{},
{
$set: {
name: {
$function: {
body: function (name) {
return encrypt(name);
},
args: ['$name'],
lang: 'js'
}
}
}
}
);
但是,我收到此错误:
server/node_modules/mongoose/lib/query.js:4777
const castError = new CastError();
^
CastError: Cast to string failed for value "{
'$function': { body: [Function: body], args: [ '$name' ], lang: 'js' }
}" (type Object) at path "name"
at model.Query.exec (/node_modules/mongoose/lib/query.js:4777:21)
at model.Query.Query.then (/node_modules/mongoose/lib/query.js:4876:15)
at processTicksAndRejections (node:internal/process/task_queues:96:5) {
messageFormat: undefined,
stringValue: '"{\n' +
" '$function': { body: [Function: body], args: [ '$name' ], lang: 'js' }\n" +
'}"',
kind: 'string',
value: {
'$function': { body: [Function: body], args: [ '$name' ], lang: 'js' }
},
path: 'name',
reason: null,
valueType: 'Object'
}
有人知道这是什么意思吗?我已经纠结了很久了谢谢
1条答案
按热度按时间6l7fqoea1#
所以你实际上有多个问题与此代码,我将开始与错误您张贴。这是一个
mongoose
铸造错误。您尝试使用aggregation $function函数作为正常更新的一部分,这是不允许的-
mongoose
又尝试将“name”值转换为字符串,因为这是它期望从模式定义中获得的。这是您得到的错误。因此,要解决问题#1,您需要使用aggregation pipeline update syntax,它将允许使用
$function
,并停止使用mongoose
,它的“模式”保护对于高级语法使用非常不利。注解中提到的第二个问题是,由于Mongodb解析和执行代码的方式,它不像普通的“编译器”那样将函数调用转换为动态代码。
相反,它将这个“对象”发送到内部引擎,并在那里尝试执行它,因此在Mongo的内部评分中没有这样的函数。
为了克服这个问题,你需要先在mongo中存储你的自定义函数,这实际上很容易,如here所述:
现在,从#1的变化,你的代码应该工作。