SPL 协助 mongodb: Replace substring in array of objects with nested objects
Mongodb 数据库中某 collection(名为 meetings)数据如下:不同的层级上都有 avatar 这个字段,共 3 种:organizer.avatar;meetings[].owner.avatar(这表示 meetings 下是数组,有多个 owner.avatar);meetings[].participants[].avatar(数组下有数组)。
[
{
"_id": ObjectId("5a934e000102030405000000"),
"eventName": "Welcome Event",
"meetings": [
{
"owner": {
"avatar": "https://old.com/dwight-schrute.png",
"name": "Dwight Schrute"
},
"participants": [
{
"avatar": "https://old.com/kevin-malonoe.png",
"name": "Kevin Malonoe"
},
{
"avatar": "https://old.com/creed-bratton.png",
"name": "Creed Bratton"
}
]
},
{
"owner": {
"avatar": "https://old.com/jim-halpert.png",
"name": "Jim Halpert"
},
"participants": [
{
"avatar": "https://old.com/pam-beesly.png",
"name": "Pam Beesly"
}
]
}
],
"organizer": {
"avatar": "https://old.com/michale-scott.png",
"name": "Michael Scott"
}
}
]
要求:把所有 avatar 字段值的开头,从https://old.com/… 改成 https://new.com/…
期望结果:
[
{
"_id": ObjectId("5a934e000102030405000000"),
"eventName": "Welcome Event",
"meetings": [
{
"owner": {
"avatar": "https://new.com/dwight-schrute.png",
"name": "Dwight Schrute"
},
"participants": [
{
"avatar": "https://new.com/kevin-malonoe.png",
"name": "Kevin Malonoe"
},
{
"avatar": "https://new.com/creed-bratton.png",
"name": "Creed Bratton"
}
]
},
{
"owner": {
"avatar": "https://new.com/jim-halpert.png",
"name": "Jim Halpert"
},
"participants": [
{
"avatar": "https://new.com/pam-beesly.png",
"name": "Pam Beesly"
}
]
}
],
"organizer": {
"avatar": "https://old.com/michale-scott.png",
"name": "Michael Scott"
}
}
]
mongodb query 写出来层级太多,很费劲,如下
db.collection.update({},
[
{
"$set": {
"meetings": {
$map: {
input: "$meetings",
in: {
$mergeObjects: [
"$$this",
{
owner: {
$mergeObjects: [
"$$this.owner",
{
avatar: {
$replaceOne: {
input: "$$this.owner.avatar",
find: "https://old.com/",
replacement: "https://new.com/"
}
}
}
]
}
},
{
participants: {
$map: {
input: "$$this.participants",
as: "p",
in: {
$mergeObjects: [
"$$p",
{
avatar: {
$replaceOne: {
input: "$$p.avatar",
find: "https://old.com/",
replacement: "https://new.com/"
}
}
}
]
}
}
}
}
]
}
}
}
}
}
])
SPL 支持点操作符逐级访问,可以把多层结构的数据修改写得很简洁易读:
A |
|
1 |
=mongo_open@d("mongodb://127.0.0.1:27017/local") |
2 |
=mongo_shell@d(A1, "{'find':'meetings','projection':{'_id':0}}") |
3 |
=mongo_close(A1) |
4 |
=A2.run(organizer.run(avatar="https://new.com/"+mid(avatar,17)), meetings.run(owner.run(avatar="https://new.com/"+mid(avatar,17)), participants.run(avatar="https://new.com/"+mid(avatar,17)) ) ) |
5 |
=json(A4) |
英文版:https://c.esproc.com/article/1741658603058