MongoDB中replaceAll功能异常:实现Step字段重试时间的添加与替换
MongoDB Step字段更新逻辑实现问题
我需要给MongoDB的Step字段实现以下逻辑:
- 若字段中不存在
[retrying HH:MM]格式的文本,就追加该内容(时间为当前时间) - 若已存在该格式的文本,就将其中的时间替换为最新的当前时间
示例:
- 添加场景:原字段值为
Waiting to receive information from the network,更新后为Waiting to receive information from the network [retrying 12:00] - 替换场景:原字段值为
Waiting to receive information from the network [retrying 12:00],更新后为Waiting to receive information from the network [retrying 12:05]
当前使用Go 1.22结合MongoDB 7.0.8的聚合操作符实现,但代码无法正常工作,代码片段如下:
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)
问题分析
原代码存在两个关键问题:
- 格式不匹配:需求中的目标格式是
[retrying HH:MM](无冒号),但代码生成的retryingInfo是[retrying: HH:MM](带冒号),正则也匹配带冒号的格式,导致实际字段内容无法被正确识别,每次都会执行追加而非替换。 - 正则使用错误:
$replaceAll的find参数直接传字符串正则时,MongoDB会当作精确字符串匹配,而非正则匹配,无法正确替换目标内容。
修正后的代码
fieldName := "$Step" // 精准匹配[retrying HH:MM]格式的正则 retryingRegex := `\s\[retrying\s\d{2}:\d{2}\]` // 修正格式:去掉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, // 使用$regex对象指定正则匹配 "find": bson.M{"$regex": retryingRegex}, "replacement": retryingInfo, }, }, "else": bson.M{ "$concat": []string{ fieldName, retryingInfo, }, }, }, }, }, }, } filter := bson.M{"_id": id} // 添加错误捕获与日志,方便排查问题 result, err := collection.UpdateOne(ctx, filter, update) if err != nil { log.Printf("更新失败: %v", err) } else { log.Printf("匹配文档数: %d, 修改文档数: %d", result.MatchedCount, result.ModifiedCount) }
补充说明
- 正则
\s\[retrying\s\d{2}:\d{2}\]仅匹配符合[retrying HH:MM]格式的内容,避免误匹配其他类似字符串 - 在
$replaceAll中使用bson.M{"$regex": retryingRegex}明确告诉MongoDB使用正则匹配而非精确字符串匹配 - 添加错误捕获和日志输出,便于排查执行过程中的问题
内容的提问来源于stack exchange,提问作者crr
相关产品推荐
相关产品推荐

