Kueri Proyeksi

Sebagian besar kueri Datastore menampilkan seluruh entity sebagai hasilnya, tetapi sering kali aplikasi sebenarnya hanya tertarik pada beberapa properti entity. Kueri proyeksi memungkinkan Anda membuat kueri Datastore untuk properti tertentu dari entity yang benar-benar Anda butuhkan, dengan latensi dan biaya yang lebih rendah daripada mengambil seluruh entity.

Kueri proyeksi mirip dengan kueri SQL berbentuk:

SELECT name, email, phone FROM CUSTOMER

Anda dapat menggunakan semua fitur pemfilteran dan pengurutan yang tersedia untuk kueri entity standar, sesuai dengan batasan yang dijelaskan di bawah. Kueri menampilkan hasil ringkas hanya dengan properti yang ditentukan (name, email, dan phone dalam contoh) yang diisi dengan nilai; semua properti lainnya tidak memiliki data.

Menggunakan kueri proyeksi di Go 1.11

Saat menyiapkan Query, tentukan proyeksi menggunakan metode Project:

q := datastore.NewQuery("People").Project("FirstName", "LastName")

Anda menangani hasil kueri ini seperti yang Anda lakukan untuk kueri entity standar: misalnya, dengan melakukan iterasi pada hasilnya.

Contoh kueri berikut adalah untuk properti Title, ReadPath, dan DateWritten dari semua entri EventLog, yang diurutkan secara menaik menurut DateWritten, dan menulis nilai setiap properti ke log aplikasi:

q := datastore.NewQuery("EventLog").
	Project("Title", "ReadPath", "DateWritten").
	Order("DateWritten")
t := q.Run(ctx)
for {
	var l EventLog
	_, err := t.Next(&l)
	if err == datastore.Done {
		break
	}
	if err != nil {
		log.Errorf(ctx, "Running query: %v", err)
		break
	}
	log.Infof(ctx, "Log record: %v, %v, %v", l.Title, l.ReadPath, l.DateWritten)
}

Pengelompokan(eksperimental)

Kueri proyeksi dapat menggunakan metode Distinct untuk memastikan bahwa hanya hasil yang benar-benar unik yang akan ditampilkan dalam kumpulan hasil. Tindakan ini hanya akan menampilkan hasil pertama untuk entity yang memiliki nilai yang sama untuk properti yang sedang diproyeksikan.

q := datastore.NewQuery("Person").
	Project("LastName", "Height").Distinct().
	Filter("Height >", 20).
	Order("-Height").Order("LastName")

Batasan proyeksi

Kueri proyeksi tunduk pada batasan berikut ini:

  • Hanya properti yang diindeks yang dapat diproyeksikan.

    Proyeksi tidak didukung untuk properti yang tidak diindeks, baik secara eksplisit maupun implisit. String yang lebih panjang dari 1.500 byte dan array byte yang memiliki lebih dari 1.500 elemen tidak diindeks.

  • Properti yang sama tidak dapat diproyeksikan lebih dari sekali.

  • Properti yang direferensikan dalam filter kesetaraan (=) tidak dapat diproyeksikan.

    Misalnya,

    SELECT A FROM kind WHERE B = 1
    

    valid (properti yang diproyeksikan tidak digunakan dalam filter kesetaraan), begitu juga

    SELECT A FROM kind WHERE A > 1
    

    (bukan filter kesetaraan), tetapi

    SELECT A FROM kind WHERE A = 1
    

    (properti proyeksi yang digunakan dalam filter kesetaraan).

  • Hasil yang ditampilkan oleh kueri proyeksi tidak boleh disimpan kembali ke Datastore.

    Karena kueri menampilkan hasil yang hanya terisi sebagian, Anda tidak boleh menulisnya kembali ke Datastore.

Proyeksi dan properti multi-nilai

Memproyeksikan properti dengan beberapa nilai tidak akan mengisi semua nilai untuk properti tersebut. Sebagai gantinya, entity terpisah akan ditampilkan untuk setiap kombinasi unik dari nilai proyeksi yang cocok dengan kueri. Misalnya, Anda memiliki entity jenis Foo dengan dua properti multi-nilai, yaitu A dan B:

entity := Foo{A: []int{1, 1, 2, 3}, B: []string{"x", "y", "x"}}

Kemudian, kueri proyeksi

q := datastore.NewQuery("Foo").Project("A", "B").Filter("A <", 3)

akan menampilkan empat entity dengan kombinasi nilai berikut:

A = 1, B = 'x'
A = 1, B = 'y'
A = 2, B = 'x'
A = 2, B = 'y'

Perhatikan bahwa jika suatu entity memiliki properti multi-nilai tanpa nilai, tidak ada entri yang akan disertakan dalam indeks, dan tidak ada hasil untuk entity tersebut yang akan ditampilkan dari kueri proyeksi yang menyertakan properti tersebut.

Indeks untuk proyeksi

Kueri proyeksi mengharuskan semua properti yang ditentukan dalam proyeksi untuk disertakan dalam indeks Datastore. Server pengembangan App Engine secara otomatis menghasilkan indeks yang diperlukan untuk Anda di file konfigurasi indeks, index.yaml, yang diupload dengan aplikasi Anda.

Salah satu cara untuk meminimalkan jumlah indeks yang diperlukan adalah dengan memproyeksikan properti yang sama secara konsisten, meskipun tidak semuanya selalu diperlukan. Misalnya, kueri ini memerlukan dua indeks terpisah:

SELECT A, B FROM Kind
SELECT A, B, C FROM Kind

Namun, jika Anda selalu memproyeksikan properti A, B, dan C, meskipun C tidak diperlukan, hanya satu indeks yang akan diperlukan.

Mengonversi kueri yang ada menjadi kueri proyeksi mungkin memerlukan pembuatan indeks baru jika properti dalam proyeksi belum disertakan pada bagian kueri yang lain. Sebagai contoh, misalnya Anda memiliki kueri yang ada seperti

SELECT * FROM Kind WHERE A > 1 ORDER BY A, B

yang memerlukan indeks

Index(Kind, A, B)

Mengonversi ini ke salah satu kueri proyeksi

SELECT C FROM Kind WHERE A > 1 ORDER BY A, B
SELECT A, B, C FROM Kind WHERE A > 1 ORDER BY A, B

memperkenalkan properti baru (C) sehingga akan memerlukan pembuatan indeks baru Index(Kind, A, B, C). Perhatikan bahwa kueri proyeksi

SELECT A, B FROM Kind WHERE A > 1 ORDER BY A, B

tidak akan mengubah indeks yang diperlukan, karena properti yang diproyeksikan, yaitu A dan B, sudah disertakan dalam kueri yang ada.