For example, Documents.
[
{
"username": "joy",
"size_info": [
{
"data1": "apple bear cat",
"data2": 100
},
{
"data1": "dog eat fog good ",
"data2": 100
},
{
"data1": "hug ill jump",
"data2": 100
}
]
}
]
I want to update the document like below.
data3
is the value split by space after getting 2 words from data1
.
When I use $substr
, I get an error:
can't convert from BSON type array to String
[
{
"username": "joy",
"size_info": [
{
"data1": "apple bear cat",
"data2": 100,
"data3": "apple bear"
},
{
"data1": "dog eat fog good ",
"data2": 100,
"data3": "dog eat"
},
{
"data1": "hug ill jump",
"data2": 100,
"data3": "hug ill"
}
]
}
]
Is it possible? Thank you for helping.
Pre-requisites: Have to update the records with the aggregation pipeline.
Solution 1: With regex
$set
- Set size_info
array.
1.1. $map
- Iterate the element in the size_info
array and return a new array.
1.1.1. $mergeObjects
- Merge the current iterated document with the result from 1.1.1.1.
1.1.1.1. A document with data3
field. Get the first capture element from the result with the regex that captures the first two words.
db.collection.update({},
[
{
$set: {
size_info: {
$map: {
input: "$size_info",
in: {
$mergeObjects: [
"$$this",
{
data3: {
$first: {
$getField: {
field: "captures",
input: {
$regexFind: {
input: "$$this.data1",
regex: "^([^\\s]* [^\\s]*).*$"
}
}
}
}
}
}
]
}
}
}
}
}
])
Demo Solution 1 @ Mongo Playground
Solution 2: Get the first N element with $firstN
Pre-requisites: MongoDB version 5.2
$set
- Set size_info
array.
1.1. $map
- Iterate the element in the size_info
array and return a new array.
1.1.1. $mergeObjects
- Merge the current iterated document with the result from 1.1.1.1.
1.1.1.1. A document with data3
field. Trim the result returned from $reduce
operator which will:
a. Split the data1
by space into an array. And take the first 2 elements.
b. Concat the value from the array (result from a) into a string with space.
db.collection.update({},
[
{
$set: {
size_info: {
$map: {
input: "$size_info",
in: {
$mergeObjects: [
"$$this",
{
data3: {
$trim: {
input: {
$reduce: {
input: {
$firstN: {
input: {
$split: [
"$$this.data1",
" "
]
},
n: 2
}
},
initialValue: "",
in: {
$concat: [
"$$value",
" ",
"$$this"
]
}
}
}
}
}
}
]
}
}
}
}
}
])