标题翻译

How to Update MongoDB doc in golang coming from React Client?

问题

抱歉,我只能为您提供翻译服务,无法执行代码或返回翻译后的代码。以下是您提供的内容的翻译:

抱歉,这是一个很长的新手帖子,但我不太确定在这里该问什么。我正在尝试在MongoDB中“保存”一个文档。该文档是通过collection.InsertOne()创建的,允许MongoDB创建_id字段。但是我无法弄清楚如何在此之后更新文档。

该文档由golang后端发送给react客户端。然后用户编辑一些字段并点击保存。

我尝试了以下代码:

filter := bson.D{}
result, err := sequencesCollection.ReplaceOne(c, filter, document)
if err != nil {
    log.Fatal(err)
}

但是它一直告诉我文档的_id已经改变了:

write exception: write errors: [After applying the update, the (immutable) field '_id' was found to have been altered to _id: "64d50067a145130ccf0521af"]

我觉得我可能在某种程度上搞乱了_id字段。我是这样获取文档的:

func getSequence(ctx *gin.Context) {
    id := ctx.Params.ByName("id")

    _id, err := primitive.ObjectIDFromHex(id)
    if err != nil {
        log.Fatal(err)
    }

    var sequence bson.M
    if err := sequencesCollection.FindOne(ctx, bson.M{"_id": _id}).Decode(&sequence); err != nil {
        log.Fatal(err)
    }

    fmt.Printf("the sequence: %s", sequence)

    ctx.JSON(http.StatusOK, sequence)
}

看起来工作正常。我可以看到_id字段是一个ObjectID。

the sequence: map[_id:ObjectID("64d50067a145130ccf0521af") currentEnvelopeId: currentPanelId:ARP deviceFamilyId:Mini/Monologue division:%!s(float64=8) envelopes:[] length:%!s(float64=3) midiDevicePreferences:map[inputs:[] outputs:[]] midiSettings:map[midiInputChannelNum:%!s(float64=-1) midiInputDeviceId: midiInputDeviceName:omni midiOutputChannelNum:%!s(float64=0) midiOutputDeviceId: midiOutputDeviceName:none midiRemoteChannelNum:%!s(float64=-1) midiRemoteDeviceId:] name:New Sequence numSteps:%!s(float64=3) packs:[] playOrder:forward rawSteps:[map[gateLength:%!s(float64=0.5) note:%!s(float64=60) velocity:%!s(float64=100)] map[gateLength:%!s(float64=0.5) note:%!s(float64=60) velocity:%!s(float64=100)] map[gateLength:%!s(float64=0.5) note:%!s(float64=72) velocity:%!s(float64=100)]] scaleSettings:map[customNotes:[] root:%!s(float64=0) scaleType:Chromatic] searchHints:map[] skin:map[backgroundColor:%!s(float64=1.671168e+07) velocityColor:%!s(float64=1.5598465e+07)] stepFilters:[] steps:[map[gateLength:%!s(float64=0.5) note:%!s(float64=60) velocity:%!s(float64=100)] map[gateLength:%!s(float64=0.5) note:%!s(float64=60) velocity:%!s(float64=100)] map[gateLength:%!s(float64=0.5) note:%!s(float64=72) velocity:%!s(float64=100)]] sysexPresetAddress:map[packId:localpack presetId:0 typeId:sysex] tempo:%!s(float64=120) user_id:62d93722d51a8f9b6685d3f6 user_name: viewSettings:map[]]

我尝试以这种方式放置文档:

func putSequence(c *gin.Context) {
    jsonData, err := io.ReadAll(c.Request.Body)
    fmt.Printf("jsonData: %s\n", jsonData)

    var document bson.M = bson.M{}
    err = json.Unmarshal(jsonData, &document)
    if err != nil {
        log.Fatal(err)
    }

    _id := document["_id"]
    filter := bson.D{{Key: "_id", Value: _id}}
    result, err := sequencesCollection.ReplaceOne(c, filter, document)
    if err != nil {
        log.Fatal(err)
    }

    c.JSON(http.StatusOK, result.UpsertedCount)
}

我以这种方式发送原始文档:

func postSequence(c *gin.Context) {
    jsonData, err := io.ReadAll(c.Request.Body)

    var document bson.M = bson.M{}
    err = json.Unmarshal(jsonData, &document)
    if err != nil {
        log.Fatal(err)
    }

    result, err := sequencesCollection.InsertOne(c, document)
    if err != nil {
        log.Fatal(err)
    }

    c.JSON(http.StatusOK, result.InsertedID)
}

我猜我的问题是...在通过JSON传递给客户端并返回时,如何保留_id字段?或者,如何替换文档?

filter := bson.D{}
result, err := sequencesCollection.ReplaceOne(c, filter, document)
if err != nil {
	log.Fatal(err)
}
func getSequence(ctx *gin.Context) {
id := ctx.Params.ByName("id")

_id, err := primitive.ObjectIDFromHex(id)
if err != nil {
	log.Fatal(err)
}

var sequence bson.M
if err := sequencesCollection.FindOne(ctx, bson.M{"_id": _id}).Decode(&sequence); err != nil {
	log.Fatal(err)
}

fmt.Printf("the sequence: %s", sequence)

ctx.JSON(http.StatusOK, sequence)
}
func putSequence(c *gin.Context) {
jsonData, err := io.ReadAll(c.Request.Body)
fmt.Printf("jsonData: %s\n", jsonData)

var document bson.M = bson.M{}
err = json.Unmarshal(jsonData, &document)
if err != nil {
	log.Fatal(err)
}

_id := document["_id"]
filter := bson.D{{Key: "_id", Value: _id}}
result, err := sequencesCollection.ReplaceOne(c, filter, document)
if err != nil {
	log.Fatal(err)
}

c.JSON(http.StatusOK, result.UpsertedCount)
}
func postSequence(c *gin.Context) {
jsonData, err := io.ReadAll(c.Request.Body)

var document bson.M = bson.M{}
err = json.Unmarshal(jsonData, &document)
if err != nil {
	log.Fatal(err)
}

result, err := sequencesCollection.InsertOne(c, document)
if err != nil {
	log.Fatal(err)
}

c.JSON(http.StatusOK, result.InsertedID)
}
答案1

得分: 0

我已经将这段代码翻译成了中文,以下是翻译的结果:

func putSequence(c *gin.Context) {
    jsonData, err := io.ReadAll(c.Request.Body)

    var document bson.M
    err = bson.UnmarshalExtJSON(jsonData, true, &document)
    if err != nil {
        log.Fatal(err)
    }

    // 修复 _id
    var hexId HexId
    err = bson.UnmarshalExtJSON(jsonData, true, &hexId)
    _id, err := primitive.ObjectIDFromHex(hexId.ID.Hex())
    if err != nil {
        log.Fatal(err)
    }
    document["_id"] = hexId.ID

    result, err := sequencesCollection.ReplaceOne(c, bson.M{"_id": _id}, document)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Printf("Modified %d document(s)\n", result.ModifiedCount)
    c.JSON(http.StatusOK, result.UpsertedCount)
}

这是 MongoDB 'AppService' 函数:

exports = async function(payload, response) {
    console.log(`hi from PutSequence. Payload:\n${JSON.stringify(payload)}`)

    if (payload.body) {
        const sequences = context.services.get("mongodb-atlas").db("Powermad").collection("sequences");

        const body = EJSON.parse(payload.body.text());
        console.log(`Parsed body:\n${JSON.stringify(body)}`)
        body._id = BSON.ObjectId(body._id);
        return await sequences.updateOne({_id: body._id }, body);
    }

    return {};
};

希望对你有帮助!

func putSequence(c *gin.Context) {
jsonData, err := io.ReadAll(c.Request.Body)

var document bson.M
err = bson.UnmarshalExtJSON(jsonData, true, &document)
if err != nil {
	log.Fatal(err)
}

// fix _id
var hexId HexId
err = bson.UnmarshalExtJSON(jsonData, true, &hexId)
_id, err := primitive.ObjectIDFromHex(hexId.ID.Hex())
if err != nil {
	log.Fatal(err)
}
document["_id"] = hexId.ID

result, err := sequencesCollection.ReplaceOne(c, bson.M{"_id": _id}, document)
if err != nil {
	log.Fatal(err)
}

fmt.Printf("Modified %d document(s)\n", result.ModifiedCount)
c.JSON(http.StatusOK, result.UpsertedCount)
}
exports = async function(payload, response) {
console.log(`hi from PutSequence. Payload:\n${JSON.stringify(payload)}`)

if (payload.body) {
  const sequences = context.services.get("mongodb-atlas").db("Powermad").collection("sequences");

  const body =  EJSON.parse(payload.body.text());
  console.log(`Parsed body:\n${JSON.stringify(body)}`)
  body._id = BSON.ObjectId(body._id);
  return await sequences.updateOne({_id: body._id }, body);
}

return  {};
};