我正在尝试在 MongoDB 聚合管道中创建一个步骤,该步骤将用屏蔽值替换完整社会保障号的值(如
"123-45-6789"
),保留最后四位数字(如 "XXX-XX-6789"
)。
我看到
$replaceAll
和 $replaceOne
但看起来它们只接受字符串文字,而不接受正则表达式。我看到有一个正则表达式发现它看起来非常笨拙地适合替换阶段:
"maskedSsn" : {
"$replaceOne" : {
"input" : "$ssn",
"find" : {
"$regexFind" : {
"input" : "$ssn",
"regex" : "\\d{3}-\\d{2}\\-"
}
},
"replacement" : "XXX-XX-"
}
}
但是这样我得到了错误
"$replaceOne requires that 'find' be a string, found: {match: \"000-00-\", idx: 0, captures: []}
(SSN 被嘲笑,这里是随机数据)。作为此步骤的一部分,我不确定如何从结果对象中获取 "match"
。我可以将此正则表达式匹配添加为不同的字段,然后在聚合的这一阶段获取匹配以进行简单的字符串替换,但如果可能的话,我更愿意将所有逻辑保留在一个步骤中。
我很难相信这不可能通过诸如正则表达式替换之类的东西一步完成(这是我使用过的每种语言的一项功能)。我缺少什么功能吗?
MongoDB 中没有通用的 regexReplace 运算符。
您可以使用 $regexFind 到达您想要的位置,例如
{$regexFind: {
input:"$ssn",
regex:"\\d{3}-\\d{2}-(\\d{4})"
}}
这将返回一个类似于以下内容的对象:
{
match: "123-45-6789",
idx: 0
captures: ["6789"]
}
您可以使用 $getField、$arrayElemAt 和 $concat 提取捕获部分,然后用它执行您需要的操作。
db.collection.aggregate([
{$addFields: {
maskedssn: {
$concat: [
"XXX-XX-",
{$arrayElemAt: [
{$getField: {
field: "captures",
input: {$regexFind: {
input: "$ssn",
regex: "\\d{3}-\\d{2}-(\\d{4})"
}}
}},
0
]}
]
}
}}
])