web-dev-qa-db-ja.com

MongoDB GolangドライバーでUpdateOneを使用すると、Upsertが機能しない

参考までに、私はこの構造体を持っています:

type OpenOrderCleaned struct {
    OrderID             string    `json:"orderId" bson:"orderId"`
    DateTimeOrderPlaced time.Time `json:"dateTimeOrderPlaced" bson:"dateTimeOrderPlaced"`
    OrderItems          []struct {
        OrderItemID   string `json:"orderItemId" bson:"orderItemId"`
        Ean           string `json:"ean" bson:"ean"`
        CancelRequest bool   `json:"cancelRequest" bson:"cancelRequest"`
        Quantity      int    `json:"quantity" bson:"quantity"`
    } `json:"orderItems" bson:"orderItems"`
}

MongoDBに保存する複数のJSONインスタンスを含むAPI応答を取得するため、forループを使用します。すべてのJSONインスタンスに固有のorderIdフィールドを使用して、ドキュメントがデータベースに既に存在するかどうかを確認したいと思います。 UpdateOneupsertがあるので、これには良いオプションだと思いました。したがって、orderIdが存在しない場合は、完全なドキュメントを生成してデータベースに保存する必要があります。

for _, OpenOrderCleaned := range o.Orders {

    c := auth.GetClient()
    collection := c.Database("goprac").Collection(x)

    filter := bson.M{"orderId": bson.M{"$eq": OpenOrderCleaned.OrderID}}
    update := bson.M{
        "$set": bson.M{
            "orderId":             OpenOrderCleaned.OrderID,
            "dateTimeOrderPlaced": OpenOrderCleaned.DateTimeOrderPlaced,
            "orderItems":          OpenOrderCleaned.OrderItems,
        },
    }

    ctx, _ := context.WithTimeout(context.Background(), 15*time.Second)
    result, err := collection.UpdateOne(ctx, filter, update)

    if err != nil {
        fmt.Println("UpdateOne() result ERROR:", err)
        os.Exit(1)
    } else {
        fmt.Println("UpdateOne() result:", result)
        fmt.Println("UpdateOne() result TYPE:", reflect.TypeOf(result))
        fmt.Println("UpdateOne() result MatchedCount:", result.MatchedCount)
        fmt.Println("UpdateOne() result ModifiedCount:", result.ModifiedCount)
        fmt.Println("UpdateOne() result UpsertedCount:", result.UpsertedCount)
        fmt.Println("UpdateOne() result UpsertedID:", result.UpsertedID)
    }

}

しかし、現在Upsertは機能していません。マニュアルドキュメントをMongoDBに入れてプログラムを実行すると、更新されます。では、なぜデータベースに新しいインスタンスが作成されないのでしょうか?どこかにupsert=Trueなどと記載する必要がありますか?または、"orderItems": OpenOrderCleaned.OrderItemsのマッピングが正しくない可能性がありますか?

どんな助けでもありがたいです。

3
Raf Rasenberg

アップサートではなく、更新を呼び出しています。アップサートするには、正しいオプションをUpdateOneに渡す必要があります。これは、mongoドライバーの例からのものです。

opts := options.Update().SetUpsert(true)
filter := bson.D{{"_id", id}}
update := bson.D{{"$set", bson.D{{"email", "[email protected]"}}}}

result, err := coll.UpdateOne(context.TODO(), filter, update, opts)

optsがありません。

9
Burak Serdar