I'm trying to append the text "[retrying: " + time.Now().Format("15:04") + "]"
in such a way that if it is missing in the field, it will be added; if it is present, it will be replaced.
For example (adding text):
{
"_id": {
"$oid": "66f134e7ad3dc5c40ced7b2a"
},
"CreatedAt": {
"$date": "2024-09-23T09:29:11.276Z"
},
"UpdatedAt": {
"$date": "2024-09-24T22:15:50.679Z"
},
"Step": "Waiting to receive information from the network"
}
Target:
{
"_id": {
"$oid": "66f134e7ad3dc5c40ced7b2a"
},
"CreatedAt": {
"$date": "2024-09-23T09:29:11.276Z"
},
"UpdatedAt": {
"$date": "2024-09-24T22:15:50.679Z"
},
"Step": "Waiting to receive information from the network [retrying 12:00]"
}
Or (replacing text)
{
"_id": {
"$oid": "66f134e7ad3dc5c40ced7b2a"
},
"CreatedAt": {
"$date": "2024-09-23T09:29:11.276Z"
},
"UpdatedAt": {
"$date": "2024-09-24T22:15:50.679Z"
},
"Step": "Waiting to receive information from the network [retrying 12:00]"
}
Target:
{
"_id": {
"$oid": "66f134e7ad3dc5c40ced7b2a"
},
"CreatedAt": {
"$date": "2024-09-23T09:29:11.276Z"
},
"UpdatedAt": {
"$date": "2024-09-24T22:15:50.679Z"
},
"Step": "Waiting to receive information from the network [retrying 12:05]"
}
Currently I have this code that I am trying with:
fieldName := "$Step"
retryingRegex := `\s\[retrying:.*\]`
retryingInfo := " [retrying: " + time.Now().Format("15:04") + "]"
update := bson.A{
bson.M{
"$set": bson.M{
"Step": bson.M{
"$cond": bson.M{
"if": bson.M{
"$regexMatch": bson.M{
"input": fieldName,
"regex": retryingRegex,
},
},
"then": bson.M{
"$replaceAll": bson.M{
"input": fieldName,
"find": retryingRegex,
"replacement": retryingInfo,
},
},
"else": bson.M{
"$concat": []string{
fieldName,
retryingInfo,
},
},
},
},
},
},
}
filter := bson.M{"_id": id}
collection.UpdateOne(ctx, filter, update)
But it doesn't seems to work. DB version v7.0.8 Go version 1.22
The problem is that in the $replaceAll
operation the find
field must be a "plain" string to find (and replace). It can't be a regular expression (more precisely it's not used as a regular expression).
What you may do is execute a $regexFind
to find the part that occurs in the value of the updatable Step
field, and replace that.
But $regexpFind
doesn't return the matching substring, it returns an object whose match
field contains the matching substring. To get its match
field, you may use $getField
.
This is how it may look like (only the "then"
branch, the rest is unchanged and omitted for brevity):
"then": bson.M{
"$replaceAll": bson.M{
"input": fieldName,
"find": bson.M{
"$getField": bson.M{
"field": "match",
"input": bson.M{
"$regexFind": bson.M{
"input": fieldName,
"regex": retryingRegex,
},
},
},
},
"replacement": retryingInfo,
},
},
Note that personally I would just store retryingInfo
in a separate field, which would result in much simpler and cleaner code. Even that formatting is unnecessary, just store the timestamp, and it can be formatted when displayed to the user.