Saya memiliki tabel DynamoDB bernama URLArray yang berisi daftar URL (myURL) dan nama video unik (myKey).
Saya perlu melakukan dua hal:
- Saat pengguna mengklik tombol video berikutnya, entri acak harus dipilih dari URLArray ini. Mungkin ada puluhan ribu baris.
Pengguna masuk ke aplikasi. Setiap kali mereka selesai menonton video, nama video unik dari video tersebut direkam. Jadi....ketika pengguna telah melihat video, video tersebut akan ditambahkan ke daftar dalam tabel bernama Pengguna di bawah baris info pengguna.
- Soo...Entri acak yang dipilih ketika pengguna mengklik tombol video berikutnya di poin 1, harus dibandingkan dengan daftar video yang telah mereka lihat. Untuk memastikan bahwa itu tidak muncul lagi secara acak untuk pengguna tertentu.
Saya melakukan sesuatu yang sangat tidak efisien sejauh ini, berhasil, tetapi tidak bagus:
Omong-omong saya menggunakan AppSync + GraphQL untuk berinteraksi dengan tabel DynamoDB. Saya pertama kali mendapatkan salinan lokal URLArray:
//Gets a list of the Key/URL pairs in the UrlArrays table in GraphQL ****IN CONSTRUCTOR, so we have this URLArray data when componentDidMount()****
listUrlArrays = async () => {
try {
URLData = await API.graphql(graphqlOperation(ListUrlArrays)); //GraphQL query
//URLData[] is available in the entire class
this.setState({urlArrayLength: apiData.data.listURLArrays.items.length}); //gets the length of URLArray (i.e. how many videos are in the database)
}
}
Sebagai gambaran umum, saat pengguna mengklik video berikutnya:
//When clicking next video
async nextVideo(){
await this.logVideosSeen(); //add myKey to the list of videos in *Users* table the logged in user has now seen
await this.getURL(); //get the NEXT upcoming video's details, for Video Player to play and make sure it's not been seen before
}
//This will update the 'listOfVideosSeen[]' in Users table with videos unique myKey, the logged in user has seen
logVideosSeen = async () => {
.......
}
async getURL() {
var dbIndex = this.getUniqueRandomNumber(this.state.urlArrayLength); //Choose a number between 0 and N number of videos in URLArray
//the hasVideoBeenSeen() basically gets the list of videos a user has already seen from `Users` table with the GraphQL getusers command, and creates a local copy of this list (can get big). I use javascripts indexOf() to check whether myKey already exists in the list
while(await this.hasVideoBeenSeen(this.state.URLData[dbIndex].myKey)) //while true i.e. user has seen that video before
{
dbIndex = this.getUniqueRandomNumber(this.state.urlArrayLength); //get another random number to fetch a new myKey
}
//If false, we'll exit the loop and know we've got a not seen before myKey, proceed to set to play...
if(dbIndex != null){
this.setState({ playURL: this.state.URLData[dbIndex].vidURL }); //Retrieve the URL from the local URLArray that we're going to play (i.e. the next video to come)
}
}
Saya dapat membagikan lebih banyak kode jika diperlukan, tetapi pada dasarnya saya ingin tahu caranya:
Biarkan fungsi Lambda memilih nomor acak berdasarkan ukuran URLArray saat ini (saya mungkin tetap perlu menyimpan salinan lokal URLArray). Tapi menurut saya poin 2 di sini sangat tidak efisien..
Biarkan fungsi Lambda memeriksa (perulangan while) terhadap tabel Pengguna apakah myKey sudah terlihat. Terutama untuk mengalihkan beban komputasi ini ke cloud, bukan ke perangkat lokal tempat aplikasi dijalankan.
SETELAH BERPIKIR................
Terima kasih atas sarannya Seth. Saya telah memikirkannya selama beberapa waktu, dan meskipun persyaratan keacakan masih berlaku, menurut saya saran Anda ada benarnya. Alasan saya memerlukan keacakan adalah agar 2 pengguna yang duduk berdampingan misalnya tidak dapat memprediksi video mana yang akan datang berikutnya. Ini bukanlah rangkaian video yang dapat diprediksi. Saya tidak yakin dapat menggunakan fungsi Scan
dengan AWS Amplify/GraphQL. Jadi ingat ada 2 hal yang terjadi di sini: (1) unggahan video, rekam di URLArray dengan bijaksana untuk referensi di masa mendatang. (2) pengguna melihat video acak yang sebelumnya tidak terlihat, lalu berpindah ke video acak lain yang tidak terlihat
*(1) Saya menyukai ide Anda dalam menggunakan angka untuk mengindeks URLArray, dan ini membantu membuat hidup menjadi lebih mudah. Jadi URL pertama berada di indeks 0, berikutnya di 1 dst…
Pemikiran saya di sini (untuk menghindari saya melakukan ListUrlArrays()
dan membawa array SELURUH secara lokal ke telepon), adalah membuat GSI bernama VideoNumber
untuk tabel URLArray. Ini akan menjadi kolom VideoNumber unik dengan angka 0-N. Jadi bayangkan diagram di atas memiliki kolom lain bernama VideoNumber. Baris 1 dengan VideoNumber disetel ke 0, Baris 2 dengan VideoNumber disetel ke 1, dll… MAKA yang perlu saya lakukan adalah secara lokal di perangkat, membuat nomor acak antara 0-N, memanggil kueri getURLArrayIdbyVideoNumber()
khusus untuk GSI tersebut, dengan nomor yang baru saja kita buat, dan itu akan membuka informasi yang saya perlukan dari baris tersebut. Voila! Saya pikir hal ini akan menghilangkan sebagian besar beban berat itu sekarang.
Pertanyaan: Sebelum setiap video diunggah, bagaimana cara dengan mudah mendapatkan jumlah total baris N saat ini dalam tabel (atau jumlah baris)? Saya kemudian akan menambahnya satu per satu.
Hal lain yang dapat saya lakukan adalah menyimpan nomor hitungan saat ini di tabel DynamoDB lain yang saya gunakan untuk data yang disimpan, membaca nomor dari sana sebelum mengunggah, dan menulis N+1 setelah mengunggah untuk menambahnya (2 operasi DynamoDB per unggahan). Itu tidak ideal.
*(2) Ketika pengguna selesai menonton video, saya dapat masuk ke daftar (di bawah informasi pengguna di DynamoDB), video mana yang sudah mereka lihat. Jadi misalnya sekarang ini bisa menjadi daftar yang terlihat: [3,12,73,108,57] untuk 5 video yang telah mereka lihat sejauh ini. Ketika pengguna mengklik nextVideo() kami akan menghasilkan nomor baru secara acak, dan langsung membandingkannya dengan nomor mana pun dalam daftar yang terlihat. Saya menggunakan seenlist.indexOf(newNumber)
dan itu akan berjalan lagi atau berhenti jika Nomor baru tidak ada dalam daftar. LALU saya dapat menelusuri kueri GSI, dan mengambil informasi yang relevan untuk menampilkan video dari URLArray.
Menurut saya indexOf()
ini adalah beban komputasi terbesar pada perangkat, dan jelas menjadi sedikit lebih lambat seiring dengan meningkatnya seenList
. Tapi itu harus lebih cepat dengan bilangan bulat murni daripada myKey
alfanumerik seperti yang saya gunakan sebelumnya. Saran lain akan diterima :)
Saya belum mencobanya, tapi itu hanya sebuah ide, karena saya harus menjaga elemen acaknya. Tapi pertama-tama, tahukah Anda bagaimana saya bisa dengan mudah menemukan jumlah baris atau jumlah tabel URLArray?