如何从MongoDB中已经存在的slug中删除特殊字符



我的MongoDB数据如下所示:

{
"_id": {
"$oid": "630f3c32c1a580642a9ff4a0"
},
"title": "This is a title [Hello#$There1234] !!5678 @",
"slug": "this--is-a-----title-[hello#$there1234]---!!5678-@----",
"Post": "this is a post"
}

但我想要这样:

{
"_id": {
"$oid": "630f3c32c1a580642a9ff4a0"
},
"title": "This is a title [Hello#$There1234] !!5678 @",
"slug": "this-is-a-title-hellothere1234-5678",
"Post": "this is a post"
}

如何只为-和字母表和数字更改slug,字母表可以是任何语言。

这里有一种方法可以通过将当前的"slug"解构为";允许的";字符,然后"$concat"将这些字符返回到单个字符串中。我有很少的regex-foo,所以我不确定这是最好的"regex",但它可能已经足够了。如果你的数据很重要,你可能应该先在一些玩具数据上测试一下。

db.collection.update({},
[
{
"$set": {
"slug": {
"$rtrim": {
"chars": "-",
"input": {
"$reduce": {
"input": {
"$regexFindAll": {
"input": "$slug",
"regex": "[\p{Xan}-]+"
}
},
"initialValue": "",
"in": {"$concat": ["$$value", "$$this.match"]}
}
}
}
}
}
}
],
{"multi": true}
)

在mongoplayground.net上试试。

更新

这有点难看,说明我缺少regex-foo,但通过添加另一个阶段来执行javascript"$function",可以将多个-压缩为一个。希望正则表达式大师能够看到这一点并简化整个过程。

db.collection.update({},
[
{
"$set": {
"slug": {
"$rtrim": {
"chars": "-",
"input": {
"$reduce": {
"input": {
"$regexFindAll": {
"input": "$slug",
"regex": "[\p{Xan}-]+"
}
},
"initialValue": "",
"in": {"$concat": ["$$value", "$$this.match"]}
}
}
}
}
}
},
{
"$set": {
"slug": {
"$function": {
"lang": "js",
"args": ["$slug"],
"body": "function(str) {return str.replace(RegExp('-+', 'g'), '-')}"
}
}
}
}
],
{
"multi": true
})

在mongoplayground.net上试试。

最新更新