I have a MongoDB collection that contains several fields with dots, like:
{
"symbol.name": "Some name"
"symbol.state": "Some state"
// etc.
}
Now, I need to rename "symbol.name" to just "symbol", and remove the rest of the fields that start with "symbol.". None of the methods worked so far for me. Usually, the field just stays the same, nothing changes. We are using Mongo 4.4 and pymongo.
Is there a working solution to this problem?
You can do the followings in an update with aggregation pipeline:
$objectToArray
of $$ROOT
into an array of kv tuples, named kv
kv
by $map
. In a $switch
, do the followings:
kv.k
equals to symbol.name
, remap the kv.k
(i.e. field name) to symbol.name
$indexOfCP
of symbol.
in kv.k
, if it is equal to 0, $set
the tuple to $$REMOVE
. This will leave null in resulting mapping result array and we will handle this in step 3$switch
, we can simply keep the kv
entry$filter
to keep only non-null entries$replaceRoot
to revert back to original object formdb.collection.update({},
[
{
"$project": {
"kv": {
"$objectToArray": "$$ROOT"
}
}
},
{
"$set": {
"kv": {
"$map": {
"input": "$kv",
"as": "kv",
"in": {
"$switch": {
"branches": [
{
// handling for symbol.name
"case": {
"$eq": [
"symbol.name",
"$$kv.k"
]
},
"then": {
k: "symbol",
v: "$$kv.v"
}
},
{
// remove fields starting by symbol.
"case": {
"$eq": [
0,
{
"$indexOfCP": [
"$$kv.k",
"symbol."
]
}
]
},
"then": "$$REMOVE"
}
],
"default": "$$kv"
}
}
}
}
}
},
{
"$set": {
// remove null fields(i.e. fields started by symbol.)
"kv": {
"$filter": {
"input": "$kv",
"as": "kv",
"cond": {
"$ne": [
"$$kv",
null
]
}
}
}
}
},
{
// revert back to original object form
"$replaceRoot": {
"newRoot": {
"$arrayToObject": "$kv"
}
}
}
],
{
multi: true
})