Reputation: 45
There are 15,000 documents in collection
This is old collection
[
{
"_id" : ObjectId("611f0b9f9964fea718ccea5f"),
"quotationNO" : "Q-000001",
"note": "21-8-2021<->send to DC<->John<#>21-8-2021<->OK<->Bob"
}
{
"_id" : ObjectId("611f2afa9964fea718ccea9c"),
"quotationNO" : "Q-000002",
"note": "22-8-2021<->send to DC<->Bob"
}
]
This is new collection . I want to modify note
field from string to object array like this. what is the best solution to do?
[
{
"_id" : ObjectId("611f0b9f9964fea718ccea5f"),
"quotationNO" : "Q-000001",
"note": [
{
"data": "21-8-2021",
"message": "send to DC",
"user": "John"
},
{
"data": "21-8-2021",
"message": "OK",
"user": "Bob"
}
]
}
{
"_id" : ObjectId("611f2afa9964fea718ccea9c"),
"quotationNO" : "Q-000002",
"note": [
{
"data": "22-8-2021",
"message": "send to DC",
"user": "Bob"
}
]
}
]
Upvotes: 0
Views: 69
Reputation: 15276
Chain up $split
and $map
to split your note
string and create the desired object. Finally do a $merge
to upsert into new_collection
.
db.collection.aggregate([
{
"$addFields": {
"note": {
"$split": [
"$note",
"<#>"
]
}
}
},
{
"$addFields": {
"note": {
"$map": {
"input": "$note",
"as": "n",
"in": {
$split: [
"$$n",
"<->"
]
}
}
}
}
},
{
"$addFields": {
"note": {
"$map": {
"input": "$note",
"as": "n",
"in": {
"data": {
"$arrayElemAt": [
"$$n",
0
]
},
"message": {
"$arrayElemAt": [
"$$n",
1
]
},
"user": {
"$arrayElemAt": [
"$$n",
2
]
}
}
}
}
}
},
{
"$merge": {
"into": "new_collection",
"on": "_id",
"whenMatched": "replace",
"whenNotMatched": "insert"
}
}
])
Here is the Mongo Playground for your reference.
Upvotes: 3
Reputation: 625
You can try following these steps:
$project
required fields and $split
note by <#>
$function
build from obtained arrays new objects by splitting elements by <->
separator and assign function result to new field note
;function(new_note){
let result = [];
for(let i = 0; i < new_note.length; i++){
const nested = new_note[i].split('<->');
result.push( {data:nested[0], message:nested[1],user:nested[2]});
}
return result
}
$project
required fields$merge
to save data in new collection.db.collection.aggregate([
{
$project: {
new_note: {
$split: [
"$note",
"<#>"
]
},
quotationNO: 1
}
},
{
$addFields: {
note: {
$function: {
body: "function(new_note){let result = []; for(let i = 0; i < new_note.length; i++){ const nested = new_note[i].split('<->'); result.push( {data:nested[0], message:nested[1],user:nested[2]}); } return result}",
args: [
"$new_note"
],
lang: "js"
}
}
}
},
{
$project: {
note: 1,
quotationNO: 1
}
},
{
$merge: {
into: "new_collection",
on: "_id",
whenMatched: "replace",
whenNotMatched: "insert"
}
}
])
Upvotes: 0