首頁  >  文章  >  後端開發  >  解組 dynamodb 項目傳回相同的項目

解組 dynamodb 項目傳回相同的項目

PHPz
PHPz轉載
2024-02-08 23:00:111041瀏覽

解组 dynamodb 项目返回相同的项目

php小編子墨今天為大家介紹如何解決解組 DynamoDB 專案回傳相同的專案的問題。 DynamoDB 是一種高效能、無伺服器的鍵值資料庫,但有時在查詢專案時可能會出現傳回相同專案的情況,這對開發者來說是一個棘手的問題。不用擔心,我們將為您提供一種解決方案,以確保您的查詢結果唯一且正確。在本文中,我們將詳細解釋問題的原因,並提供一個簡單有效的方法來解決這個問題。讓我們一起來看看吧!

問題內容

我在 golang 中有一個範圍循環,它循環使用 dynamodb 使用掃描函數傳回的 type.attributevalues 的對應。

我使用 golang aws-sdk-v2 套件 attributevalue.unmarshalmap() 提供的內建函數循環遍歷這片地圖,發生的情況是我得到了與切片長度相同的項目的返回。

程式碼:

type users struct {
    user *string `dynamodbav:"user"` 
    email *string `dynamodbav:"email"` 
    }

    user := users{}
  
   for _ , dbitem := range dynamoresults.items { 
    err = attributevalue.unmarshalmap(dbitem, &user)
   }

// gives the same pointer location for all 
users[0].user 
users[1].user
users[2].user

我還嘗試將使用者附加到結果中的切片中

// this just gives a slice with the same items as above
 u := []Users{}
for _ , dbItem := range dynamoResults.Items { 
        err = attributevalue.UnmarshalMap(dbItem, &Users)
        u = append(u, Users)
       }

我發現使用 attributevalue.unmarshallistofmaps() 的解決方案只需為該函數提供來自 dynamodb 的 items 切片。

我的問題實際上是要理解為什麼使用上述兩個解決方案不能按預期工作,不會循環遍歷 dynamodb 項並將它們單獨傳遞給 unmarshal 函數嗎?看來只是繼續做同樣的事情。

解決方法

如果我們稍微改變一下問題——從 dynamo db 解組到 json 解組——那麼我們就可以在 go 遊樂場。在範例程式碼中,我看到兩個因素共同作用導致了重複的切片值:

  1. 解組目標是在循環外部定義的(第51 行),因此當解組u1out 時,結果會寫入每次循環迭代的相同位置(第54 行) 。

  2. user1 類型的欄位為*string,因此當循環變數值複製到切片時(第55 行),useremail 指向的字串不會被複製。僅複製它們的指標值。

將這兩個放在一起,每次迭代都會將未編組的 useremail 值寫入相同內部位置。輸出的前兩行證明了這一點,它們印出 u1out 的元素。

輸出的其餘行顯示其他三種情況下的結果:當目標變數在迴圈內移動(u1inu2in)或欄位變更為stringu2out)時。在每種情況下,都會按預期建立未編組值的新位置,並且不會列印重複項。

package main

import (
    "encoding/json"
    "fmt"
)

type (
    Users1 struct {
        User  *string
        Email *string
    }
    Users2 struct {
        User  string
        Email string
    }
)

func main() {
    dbItems := []string{
        `{"User":"userA","Email":"<a href="https://www.php.cn/link/89fee0513b6668e555959f5dc23238e9" class="__cf_email__" data-cfemail="a7d2d4c2d5e6e7c2dfc6cad7cbc289c4c8ca">[email&#160;protected]</a>"}`,
        `{"User":"userB","Email":"<a href="https://www.php.cn/link/89fee0513b6668e555959f5dc23238e9" class="__cf_email__" data-cfemail="5a2f293f28181a3f223b372a363f74393537">[email&#160;protected]</a>"}`,
    }

    u1Out := withVarDeclaredOutsideLoop[Users1](dbItems)
    printUsers(u1Out)

    u1In := withVarDeclaredInsideLoop[Users1](dbItems)
    printUsers(u1In)

    u2Out := withVarDeclaredOutsideLoop[Users2](dbItems)
    printUsers(u2Out)

    u2In := withVarDeclaredInsideLoop[Users2](dbItems)
    printUsers(u2In)

    // Output
    // u[0] = {User:0xc000014130 Email:0xc000014140}
    // u[1] = {User:0xc000014130 Email:0xc000014140}
    // u[0] = {User:0xc0000141c0 Email:0xc0000141d0}
    // u[1] = {User:0xc000014210 Email:0xc000014220}
    // u[0] = {User:userA Email:<a href="https://www.php.cn/link/89fee0513b6668e555959f5dc23238e9" class="__cf_email__" data-cfemail="86f3f5e3f4c7c6e3fee7ebf6eae3a8e5e9eb">[email&#160;protected]</a>}
    // u[1] = {User:userB Email:<a href="https://www.php.cn/link/89fee0513b6668e555959f5dc23238e9" class="__cf_email__" data-cfemail="07727462754547627f666a776b622964686a">[email&#160;protected]</a>}
    // u[0] = {User:userA Email:<a href="https://www.php.cn/link/89fee0513b6668e555959f5dc23238e9" class="__cf_email__" data-cfemail="98edebfdead9d8fde0f9f5e8f4fdb6fbf7f5">[email&#160;protected]</a>}
    // u[1] = {User:userB Email:<a href="https://www.php.cn/link/89fee0513b6668e555959f5dc23238e9" class="__cf_email__" data-cfemail="fe8b8d9b8cbcbe9b869f938e929bd09d9193">[email&#160;protected]</a>}
}

func withVarDeclaredOutsideLoop[T any](dbItems []string) []T {
    var t T
    u := []T{}
    for _, dbItem := range dbItems {
        json.Unmarshal([]byte(dbItem), &t)
        u = append(u, t)
    }
    return u
}

func withVarDeclaredInsideLoop[T any](dbItems []string) []T {
    u := []T{}
    for _, dbItem := range dbItems {
        var t T
        json.Unmarshal([]byte(dbItem), &t)
        u = append(u, t)
    }
    return u
}

func printUsers[T any](u []T) {
    for i, user := range u {
        fmt.Printf("u[%d] = %+v\n", i, user)
    }
}

以上是解組 dynamodb 項目傳回相同的項目的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:stackoverflow.com。如有侵權,請聯絡admin@php.cn刪除