SPL assists MongoDB: Replace substring in array of objects with nested objects
The data for a collection (named meetings) in the MongoDB database is as follows: there are three types of avatar fields at different levels: organizer.avatar; meetings[].owner.avatar (this means that there is an array under meetings with multiple owner.avatars); meetings[].participants[].avatar (there is an array under the array).
[
{
"_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"
}
}
]
Requirement: Change the beginnings of all avatar field values from https://old.com/…. to https://new.com/….
Expected results:
[
{
"_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"
}
}
]
Writing a MongoDB query with too many levels can be quite challenging, as shown below:
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 supports dot operator for hierarchical access, which can make data modification in multi-layer structures very concise and easy to read:
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) |
SPL Official Website 👉 https://www.esproc.com
SPL Feedback and Help 👉 https://www.reddit.com/r/esProcSPL
SPL Learning Material 👉 https://c.esproc.com
SPL Source Code and Package 👉 https://github.com/SPLWare/esProc
Discord 👉 https://discord.gg/2bkGwqTj
Youtube 👉 https://www.youtube.com/@esProc_SPL
中文版:https://c.raqsoft.com.cn/article/1741585729910