Indeks

Setiap kueri Firestore dalam mode Datastore menghitung hasilnya menggunakan satu atau beberapa indeks yang berisi kunci entity dalam urutan yang ditentukan oleh properti indeks dan, secara opsional, ancestor entity. Indeks diperbarui untuk mencerminkan setiap perubahan yang dilakukan aplikasi pada entity-nya, sehingga hasil yang benar dari semua kueri tersedia tanpa perlu komputasi lebih lanjut.

Ada dua jenis indeks:

Indeks bawaan
Secara default, database mode Datastore secara otomatis menetapkan indeks terlebih dahulu untuk setiap properti dari setiap jenis entity. Indeks properti tunggal ini cocok untuk jenis kueri sederhana.
Indeks komposit
Indeks komposit mengindeks beberapa nilai properti per entity yang diindeks. Indeks gabungan mendukung kueri kompleks dan ditentukan dalam file konfigurasi indeks (index.yaml).

Jenis indeks akan dibahas secara lebih mendetail nanti.

Definisi dan struktur indeks

Indeks ditentukan pada daftar properti dari jenis entity tertentu, dengan urutan yang sesuai (menaik atau menurun) untuk setiap properti. Untuk digunakan dengan kueri ancestor, indeks juga dapat menyertakan ancestor entity secara opsional.

Indeks berisi entri untuk setiap properti yang disebutkan dalam definisi indeks. Setiap entri indeks mewakili entity yang merupakan kemungkinan hasil untuk kueri berdasarkan indeks. Entity disertakan dalam indeks hanya jika memiliki nilai yang diindeks yang ditetapkan untuk setiap properti yang digunakan dalam indeks; jika definisi indeks mengacu pada properti yang tidak memiliki nilai untuk entity, entity tersebut tidak akan muncul dalam indeks dan oleh karena itu tidak akan pernah ditampilkan sebagai hasil untuk kueri apa pun berdasarkan indeks.

Indeks komposit diurutkan terlebih dahulu berdasarkan ancestor, lalu berdasarkan nilai properti, dalam urutan yang ditentukan dalam definisi indeks. Berdasarkan pemahaman ini, Anda dapat membuat indeks sempurna yang memungkinkan kueri yang efisien.

Konfigurasi indeks

Firestore dalam mode Datastore menyediakan indeks bawaan, atau otomatis, untuk kueri dalam bentuk berikut:

  • Kueri Kindless hanya menggunakan ancestor dan filter kunci
  • Kueri yang hanya menggunakan filter ancestor dan kesetaraan
  • Kueri yang hanya menggunakan filter ketidaksetaraan (yang terbatas untuk satu properti)
  • Kueri yang hanya menggunakan filter ancestor, filter kesetaraan pada properti, dan filter ketidaksetaraan pada kunci
  • Kueri tanpa filter dan hanya satu tata urutan di satu properti, baik menaik ataupun menurun

Sebagai contoh, secara default, database mode Datastore secara otomatis menentukan dua indeks properti tunggal untuk setiap properti dari setiap jenis entity, satu dalam urutan menaik dan satu dalam urutan menurun. Jika Anda tidak ingin database mempertahankan indeks untuk properti, kecualikan properti dari indeks Anda. Perhatikan bahwa mengecualikan properti akan menghapusnya dari indeks gabungan.

Indeks bawaan cukup untuk menjalankan banyak kueri sederhana, seperti kueri khusus kesetaraan dan kueri ketidaksetaraan sederhana.

Indeks bawaan tidak muncul di halaman Indexes di konsol Google Cloud.

Untuk kueri yang lebih kompleks, aplikasi harus menentukan indeks komposit, atau manual. Indeks komposit diperlukan untuk kueri dalam bentuk berikut:

  • Kueri dengan filter ancestor dan ketidaksetaraan
  • Kueri dengan satu atau beberapa filter ketidaksetaraan di sebuah properti dan satu atau beberapa filter kesetaraan di properti lainnya
  • Kueri dengan tata urutan pada kunci dalam urutan menurun
  • Kueri dengan beberapa tata urutan
  • Kueri dengan satu atau beberapa filter dan satu atau beberapa tata urutan

Indeks komposit ditentukan dalam file konfigurasi indeks (index.yaml) aplikasi. (Indeks bawaan tidak terdapat dalam file konfigurasi indeks.)

Indeks komposit terdiri dari beberapa properti dan mewajibkan agar setiap properti tidak dikecualikan dari indeks Anda.

Indeks gabungan dapat dilihat di halaman Indexes di konsol Google Cloud. Anda tidak dapat menggunakan konsol Google Cloud untuk membuat atau memperbarui indeks komposit.

Jika aplikasi mencoba menjalankan kueri yang tidak dapat dijalankan dengan indeks yang tersedia (baik bawaan maupun yang ditentukan dalam file konfigurasi indeks), kueri akan gagal.

API mode Datastore secara otomatis menyarankan indeks yang sesuai untuk sebagian besar aplikasi. Bergantung pada penggunaan database mode Datastore aplikasi Anda serta ukuran dan bentuk data Anda, mungkin diperlukan penyesuaian manual pada indeks Anda. Misalnya, menulis entity dengan beberapa nilai properti dapat menghasilkan exploding index dengan biaya penyimpanan yang tinggi dan peningkatan latensi tulis.

Emulator Datastore dapat membantu mempermudah pengelolaan file konfigurasi indeks Anda. Menghindari kegagalan dalam menjalankan sebuah kueri yang memerlukan indeks namun tidak memilikinya, emulator Datastore dapat menghasilkan konfigurasi indeks yang memungkinkan kueri untuk berhasil. Jika pengujian lokal suatu aplikasi menjalankan setiap kemungkinan kueri yang akan dikeluarkan aplikasi, menggunakan setiap kombinasi filter dan tata urutan, entri yang dihasilkan akan mewakili set indeks lengkap. Jika pengujian Anda tidak menjalankan semua bentuk kueri yang dimungkinkan, Anda dapat meninjau dan menyesuaikan file konfigurasi indeks sebelum memperbarui indeks.

Anda dapat mempelajari index.yaml lebih lanjut di Konfigurasi Indeks.

Men-deploy atau menghapus indeks

Setelah selesai mengubah file konfigurasi indeks, jalankan perintah gcloud datastore indexes create untuk menempatkan indeks ke dalam layanan. Pelajari lebih lanjut di memperbarui indeks.

Jika sebelumnya Anda men-deploy indeks yang tidak lagi diperlukan, Anda dapat menghapus indeks yang tidak digunakan.

Biaya penyimpanan dan latensi operasi tulis

Indeks berkontribusi pada biaya penyimpanan Anda. Ukuran entri indeks menjelaskan kontribusi indeks bawaan dan komposit terhadap ukuran penyimpanan database Anda. Anda dapat menggunakan statistik Firestore dalam mode Datastore untuk melihat informasi selengkapnya tentang entri indeks dan ukuran penyimpanan indeks.

Indeks juga berkontribusi pada latensi tulis. Saat memperbarui nilai properti, database juga memperbarui setiap indeks terkait. Makin banyak indeks yang perlu diupdate database, makin lama operasinya.

Anda dapat mengurangi biaya penyimpanan dan meningkatkan performa penulisan dengan menghapus indeks yang tidak digunakan dan mengecualikan properti dari pengindeksan. Hal ini juga mencegah operasi gagal karena batas indeks.

Indeks dan properti

Berikut adalah beberapa pertimbangan khusus yang perlu diingat tentang indeks dan kaitannya dengan properti entity Anda:

Properti dengan jenis nilai campuran

Jika dua entity memiliki properti dengan nama yang sama tetapi jenis nilai yang berbeda, indeks properti akan terlebih dahulu mengurutkan entity berdasarkan jenis nilai, lalu berdasarkan pengurutan sekunder yang sesuai dengan setiap jenis. Misalnya, jika dua entity masing-masing memiliki properti bernama age, satu dengan nilai bilangan bulat dan satu dengan nilai string, entity dengan nilai bilangan bulat selalu mendahului entity dengan nilai string ketika diurutkan berdasarkan properti age, terlepas dari nilai properti itu sendiri.

Hal ini perlu diperhatikan terutama dalam kasus bilangan bulat dan angka floating point, yang diperlakukan sebagai jenis terpisah oleh mode Datastore. Karena semua bilangan bulat diurutkan sebelum semua float, properti dengan nilai bilangan bulat 38 diurutkan sebelum properti dengan nilai floating point 37.5.

Properti yang dikecualikan

Jika mengetahui bahwa Anda tidak perlu memfilter atau mengurutkan properti tertentu, Anda dapat memberi tahu database mode Datastore agar tidak mempertahankan entri indeks untuk properti tersebut dengan mengecualikannya dari indeks. Hal ini akan menurunkan biaya menjalankan aplikasi Anda dengan mengurangi ukuran penyimpanan yang diperlukan untuk entri indeks. Hal ini juga dapat meningkatkan latensi tulis. Entity dengan properti yang dikecualikan berperilaku seolah-olah properti tersebut tidak ditetapkan: kueri dengan filter atau tata urutan di properti yang dikecualikan tidak akan pernah cocok dengan entity tersebut.

Properti description dalam contoh berikut dikecualikan dari indeks:

C#

Untuk mempelajari cara menginstal dan menggunakan library klien untuk Cloud Datastore, lihat Library klien Cloud Datastore. Untuk mengetahui informasi selengkapnya, lihat dokumentasi referensi API C# Cloud Datastore.

Untuk melakukan autentikasi ke Cloud Datastore, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, lihat Menyiapkan autentikasi untuk lingkungan pengembangan lokal.

Entity task = new Entity()
{
    Key = _db.CreateKeyFactory("Task").CreateKey("sampleTask"),
    ["category"] = "Personal",
    ["created"] = new DateTime(1999, 01, 01, 0, 0, 0, DateTimeKind.Utc),
    ["done"] = false,
    ["priority"] = 4,
    ["percent_complete"] = 10.0,
    ["description"] = new Value()
    {
        StringValue = "Learn Cloud Datastore",
        ExcludeFromIndexes = true
    },
};

Go

Untuk mempelajari cara menginstal dan menggunakan library klien untuk Cloud Datastore, lihat Library klien Cloud Datastore. Untuk mengetahui informasi selengkapnya, lihat dokumentasi referensi API Go Cloud Datastore.

Untuk melakukan autentikasi ke Cloud Datastore, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, lihat Menyiapkan autentikasi untuk lingkungan pengembangan lokal.

type Task struct {
	Category        string
	Done            bool
	Priority        int
	Description     string `datastore:",noindex"`
	PercentComplete float64
	Created         time.Time
}
task := &Task{
	Category:        "Personal",
	Done:            false,
	Priority:        4,
	Description:     "Learn Cloud Datastore",
	PercentComplete: 10.0,
	Created:         time.Now(),
}

Java

Untuk mempelajari cara menginstal dan menggunakan library klien untuk Cloud Datastore, lihat Library klien Cloud Datastore. Untuk mengetahui informasi selengkapnya, lihat dokumentasi referensi API Java Cloud Datastore.

Untuk melakukan autentikasi ke Cloud Datastore, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, lihat Menyiapkan autentikasi untuk lingkungan pengembangan lokal.

Entity task =
    Entity.newBuilder(taskKey)
        .set("category", "Personal")
        .set("created", Timestamp.now())
        .set("done", false)
        .set("priority", 4)
        .set("percent_complete", 10.0)
        .set(
            "description",
            StringValue.newBuilder("Learn Cloud Datastore").setExcludeFromIndexes(true).build())
        .build();

Node.js

Untuk mempelajari cara menginstal dan menggunakan library klien untuk Cloud Datastore, lihat Library klien Cloud Datastore. Untuk mengetahui informasi selengkapnya, lihat dokumentasi referensi API Node.js Cloud Datastore.

Untuk melakukan autentikasi ke Cloud Datastore, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, lihat Menyiapkan autentikasi untuk lingkungan pengembangan lokal.

const task = [
  {
    name: 'category',
    value: 'Personal',
  },
  {
    name: 'created',
    value: new Date(),
  },
  {
    name: 'done',
    value: false,
  },
  {
    name: 'priority',
    value: 4,
  },
  {
    name: 'percent_complete',
    value: 10.0,
  },
  {
    name: 'description',
    value: 'Learn Cloud Datastore',
    excludeFromIndexes: true,
  },
];

PHP

Untuk mempelajari cara menginstal dan menggunakan library klien untuk Cloud Datastore, lihat Library klien Cloud Datastore. Untuk mengetahui informasi selengkapnya, lihat dokumentasi referensi API PHP Cloud Datastore.

Untuk melakukan autentikasi ke Cloud Datastore, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, lihat Menyiapkan autentikasi untuk lingkungan pengembangan lokal.

$task = $datastore->entity(
    $key,
    [
        'category' => 'Personal',
        'created' => new DateTime(),
        'done' => false,
        'priority' => 4,
        'percent_complete' => 10.0,
        'description' => 'Learn Cloud Datastore'
    ],
    ['excludeFromIndexes' => ['description']]
);

Python

Untuk mempelajari cara menginstal dan menggunakan library klien untuk Cloud Datastore, lihat Library klien Cloud Datastore. Untuk mengetahui informasi selengkapnya, lihat dokumentasi referensi API Python Cloud Datastore.

Untuk melakukan autentikasi ke Cloud Datastore, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, lihat Menyiapkan autentikasi untuk lingkungan pengembangan lokal.

from google.cloud import datastore

# For help authenticating your client, visit
# https://cloud.google.com/docs/authentication/getting-started
client = datastore.Client()

import datetime

key = client.key("Task")
task = datastore.Entity(key, exclude_from_indexes=("description",))
task.update(
    {
        "category": "Personal",
        "description": "Learn Cloud Datastore",
        "created": datetime.datetime.now(tz=datetime.timezone.utc),
        "done": False,
        "priority": 4,
        "percent_complete": 10.5,
    }
)
client.put(task)

Ruby

Untuk mempelajari cara menginstal dan menggunakan library klien untuk Cloud Datastore, lihat Library klien Cloud Datastore. Untuk mengetahui informasi selengkapnya, lihat dokumentasi referensi API Ruby Cloud Datastore.

Untuk melakukan autentikasi ke Cloud Datastore, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, lihat Menyiapkan autentikasi untuk lingkungan pengembangan lokal.

task = datastore.entity "Task" do |t|
  t["category"] = "Personal"
  t["created"] = Time.now
  t["done"] = false
  t["priority"] = 4
  t["percent_complete"] = 10.0
  t["description"] = "Learn Cloud Datastore"
  t.exclude_from_indexes! "description", true
end

GQL

Tidak Berlaku

Kueri dalam contoh berikut tidak akan menampilkan hasil apa pun jika properti description dikecualikan:

C#

Untuk mempelajari cara menginstal dan menggunakan library klien untuk Cloud Datastore, lihat Library klien Cloud Datastore. Untuk mengetahui informasi selengkapnya, lihat dokumentasi referensi API C# Cloud Datastore.

Untuk melakukan autentikasi ke Cloud Datastore, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, lihat Menyiapkan autentikasi untuk lingkungan pengembangan lokal.

Query query = new Query("Task")
{
    Filter = Filter.Equal("description", "Learn Cloud Datastore")
};

Go

Untuk mempelajari cara menginstal dan menggunakan library klien untuk Cloud Datastore, lihat Library klien Cloud Datastore. Untuk mengetahui informasi selengkapnya, lihat dokumentasi referensi API Go Cloud Datastore.

Untuk melakukan autentikasi ke Cloud Datastore, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, lihat Menyiapkan autentikasi untuk lingkungan pengembangan lokal.

query := datastore.NewQuery("Tasks").
	FilterField("Description", "=", "A task description")

Java

Untuk mempelajari cara menginstal dan menggunakan library klien untuk Cloud Datastore, lihat Library klien Cloud Datastore. Untuk mengetahui informasi selengkapnya, lihat dokumentasi referensi API Java Cloud Datastore.

Untuk melakukan autentikasi ke Cloud Datastore, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, lihat Menyiapkan autentikasi untuk lingkungan pengembangan lokal.

Query<Entity> query =
    Query.newEntityQueryBuilder()
        .setKind("Task")
        .setFilter(PropertyFilter.eq("description", "A task description"))
        .build();

Node.js

Untuk mempelajari cara menginstal dan menggunakan library klien untuk Cloud Datastore, lihat Library klien Cloud Datastore. Untuk mengetahui informasi selengkapnya, lihat dokumentasi referensi API Node.js Cloud Datastore.

Untuk melakukan autentikasi ke Cloud Datastore, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, lihat Menyiapkan autentikasi untuk lingkungan pengembangan lokal.

const query = datastore
  .createQuery('Task')
  .filter(new PropertyFilter('description', '=', 'A task description.'));

PHP

Untuk mempelajari cara menginstal dan menggunakan library klien untuk Cloud Datastore, lihat Library klien Cloud Datastore. Untuk mengetahui informasi selengkapnya, lihat dokumentasi referensi API PHP Cloud Datastore.

Untuk melakukan autentikasi ke Cloud Datastore, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, lihat Menyiapkan autentikasi untuk lingkungan pengembangan lokal.

$query = $datastore->query()
    ->kind('Task')
    ->filter('description', '=', 'A task description.');

Python

Untuk mempelajari cara menginstal dan menggunakan library klien untuk Cloud Datastore, lihat Library klien Cloud Datastore. Untuk mengetahui informasi selengkapnya, lihat dokumentasi referensi API Python Cloud Datastore.

Untuk melakukan autentikasi ke Cloud Datastore, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, lihat Menyiapkan autentikasi untuk lingkungan pengembangan lokal.

from google.cloud import datastore

# For help authenticating your client, visit
# https://cloud.google.com/docs/authentication/getting-started
client = datastore.Client()

query = client.query(kind="Task")
query.add_filter(
    filter=datastore.query.PropertyFilter(
        "description", "=", "Learn Cloud Datastore"
    )
)

Ruby

Untuk mempelajari cara menginstal dan menggunakan library klien untuk Cloud Datastore, lihat Library klien Cloud Datastore. Untuk mengetahui informasi selengkapnya, lihat dokumentasi referensi API Ruby Cloud Datastore.

Untuk melakukan autentikasi ke Cloud Datastore, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, lihat Menyiapkan autentikasi untuk lingkungan pengembangan lokal.

query = datastore.query("Task")
                 .where("description", "=", "A task description.")

GQL

# Will not return any results!
SELECT * FROM Task WHERE description = 'A task description.'

Nantinya, Anda dapat mengubah properti agar kembali diindeks.

Namun, perhatikan bahwa mengubah properti dari dikecualikan menjadi diindeks tidak memengaruhi entity yang sudah ada yang mungkin telah dibuat sebelum perubahan tersebut. Pemfilteran kueri pada properti tidak akan menampilkan entity yang sudah ada tersebut, karena entity tersebut tidak ditulis ke indeks kueri saat dibuat. Agar entity dapat diakses oleh kueri mendatang, Anda harus menulis ulang entity tersebut ke database agar dapat dimasukkan dalam indeks yang sesuai. Artinya, Anda harus melakukan hal berikut untuk setiap entity yang sudah ada:

  1. Cari (dapatkan) entity.
  2. Menulis (put) entity kembali ke database Anda.

Demikian pula, mengubah properti dari diindeks menjadi dikecualikan hanya memengaruhi entity yang kemudian ditulis ke database Anda. Entri indeks untuk setiap entity yang ada dengan properti tersebut akan tetap ada sampai entity tersebut diperbarui atau dihapus. Untuk menghindari hasil yang tidak diinginkan, Anda harus menghapus permanen kode dari semua kueri yang memfilter atau mengurutkan berdasarkan properti (yang kini dikecualikan).

Batas indeks

Firestore dalam mode Datastore menetapkan batas jumlah dan ukuran keseluruhan entri indeks yang dapat dikaitkan dengan satu entity. Batas ini cukup besar, dan sebagian besar aplikasi tidak terpengaruh. Namun, ada situasi saat Anda mungkin mencapai batas tersebut.

Seperti yang dijelaskan di atas, database mode Datastore membuat entri dalam indeks yang telah ditentukan untuk setiap properti dari setiap entity, kecuali yang telah Anda deklarasikan secara eksplisit sebagai dikecualikan dari indeks. Properti juga dapat disertakan dalam indeks kustom tambahan yang dideklarasikan di file konfigurasi indeks (index.yaml) Anda. Asalkan suatu entity tidak memiliki properti daftar, entity akan memiliki maksimal satu entri di setiap indeks kustom tersebut (untuk indeks non-ancestor) atau satu entri untuk setiap ancestor entity (untuk indeks ancestor). Setiap entri indeks ini harus diperbarui setiap kali nilai properti berubah.

Untuk properti yang memiliki nilai tunggal untuk setiap entity, setiap kemungkinan nilai hanya perlu disimpan sekali per entity dalam indeks properti yang telah ditentukan. Meskipun demikian, entity dengan banyak properti bernilai tunggal dapat melebihi batas entri indeks atau batas ukuran. Demikian pula, entity yang dapat memiliki beberapa nilai untuk properti yang sama memerlukan entri indeks terpisah untuk setiap nilai; sekali lagi, jika jumlah kemungkinan nilainya besar, entity tersebut dapat melebihi batas entri.

Situasi ini menjadi lebih buruk jika entity memiliki beberapa properti, yang masing-masing dapat memiliki banyak nilai. Untuk mengakomodasi entity semacam itu, indeks harus menyertakan entri untuk setiap kemungkinan kombinasi nilai properti. Indeks kustom yang merujuk ke beberapa properti, yang masing-masing dengan beberapa nilai, kombinasinya dapat "meledak", sehingga memerlukan banyak entri untuk entity yang hanya memiliki sedikit kemungkinan nilai properti. Indeks yang meledak tersebut dapat secara drastis meningkatkan ukuran penyimpanan entity, karena banyaknya jumlah entri indeks yang harus disimpan. Indeks yang meledak juga dapat menyebabkan entity melebihi batas ukuran atau jumlah entri indeks.

Pertimbangkan kode berikut:

C#

Untuk mempelajari cara menginstal dan menggunakan library klien untuk Cloud Datastore, lihat Library klien Cloud Datastore. Untuk mengetahui informasi selengkapnya, lihat dokumentasi referensi API C# Cloud Datastore.

Untuk melakukan autentikasi ke Cloud Datastore, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, lihat Menyiapkan autentikasi untuk lingkungan pengembangan lokal.

Entity task = new Entity()
{
    Key = _db.CreateKeyFactory("Task").CreateKey("sampleTask"),
    ["tags"] = new ArrayValue() { Values = { "fun", "programming", "learn" } },
    ["collaborators"] = new ArrayValue() { Values = { "alice", "bob", "charlie" } },
    ["created"] = DateTime.UtcNow
};

Go

Untuk mempelajari cara menginstal dan menggunakan library klien untuk Cloud Datastore, lihat Library klien Cloud Datastore. Untuk mengetahui informasi selengkapnya, lihat dokumentasi referensi API Go Cloud Datastore.

Untuk melakukan autentikasi ke Cloud Datastore, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, lihat Menyiapkan autentikasi untuk lingkungan pengembangan lokal.

task := &Task{
	Tags:          []string{"fun", "programming", "learn"},
	Collaborators: []string{"alice", "bob", "charlie"},
	Created:       time.Now(),
}

Java

Untuk mempelajari cara menginstal dan menggunakan library klien untuk Cloud Datastore, lihat Library klien Cloud Datastore. Untuk mengetahui informasi selengkapnya, lihat dokumentasi referensi API Java Cloud Datastore.

Untuk melakukan autentikasi ke Cloud Datastore, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, lihat Menyiapkan autentikasi untuk lingkungan pengembangan lokal.

Entity task =
    Entity.newBuilder(taskKey)
        .set("tags", "fun", "programming", "learn")
        .set("collaborators", "alice", "bob", "charlie")
        .set("created", Timestamp.now())
        .build();

Node.js

Untuk mempelajari cara menginstal dan menggunakan library klien untuk Cloud Datastore, lihat Library klien Cloud Datastore. Untuk mengetahui informasi selengkapnya, lihat dokumentasi referensi API Node.js Cloud Datastore.

Untuk melakukan autentikasi ke Cloud Datastore, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, lihat Menyiapkan autentikasi untuk lingkungan pengembangan lokal.

const task = {
  method: 'insert',
  key: datastore.key('Task'),
  data: {
    tags: ['fun', 'programming', 'learn'],
    collaborators: ['alice', 'bob', 'charlie'],
    created: new Date(),
  },
};

PHP

Untuk mempelajari cara menginstal dan menggunakan library klien untuk Cloud Datastore, lihat Library klien Cloud Datastore. Untuk mengetahui informasi selengkapnya, lihat dokumentasi referensi API PHP Cloud Datastore.

Untuk melakukan autentikasi ke Cloud Datastore, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, lihat Menyiapkan autentikasi untuk lingkungan pengembangan lokal.

$task = $datastore->entity(
    $datastore->key('Task'),
    [
        'tags' => ['fun', 'programming', 'learn'],
        'collaborators' => ['alice', 'bob', 'charlie'],
        'created' => new DateTime(),
    ]
);

Python

Untuk mempelajari cara menginstal dan menggunakan library klien untuk Cloud Datastore, lihat Library klien Cloud Datastore. Untuk mengetahui informasi selengkapnya, lihat dokumentasi referensi API Python Cloud Datastore.

Untuk melakukan autentikasi ke Cloud Datastore, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, lihat Menyiapkan autentikasi untuk lingkungan pengembangan lokal.

from google.cloud import datastore

# For help authenticating your client, visit
# https://cloud.google.com/docs/authentication/getting-started
client = datastore.Client()

import datetime

task = datastore.Entity(client.key("Task"))
task.update(
    {
        "tags": ["fun", "programming", "learn"],
        "collaborators": ["alice", "bob", "charlie"],
        "created": datetime.datetime.now(tz=datetime.timezone.utc),
    }
)

Ruby

Untuk mempelajari cara menginstal dan menggunakan library klien untuk Cloud Datastore, lihat Library klien Cloud Datastore. Untuk mengetahui informasi selengkapnya, lihat dokumentasi referensi API Ruby Cloud Datastore.

Untuk melakukan autentikasi ke Cloud Datastore, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, lihat Menyiapkan autentikasi untuk lingkungan pengembangan lokal.

task = datastore.entity "Task" do |t|
  t["tags"] = ["fun", "programming", "learn"]
  t["collaborators"] = ["alice", "bob", "charlie"]
  t["created"] = Time.now
end

GQL

Tidak Berlaku

Tindakan ini akan membuat entity Task dengan tiga nilai untuk properti tags, tiga nilai untuk properti collaborators, dan created yang ditetapkan ke tanggal saat ini. Ini akan memerlukan 9 entri indeks, satu untuk setiap kemungkinan kombinasi nilai properti:

('fun', 'alice', NOW())
('fun', 'bob', NOW())
('fun', 'charlie', NOW())

('programming', 'alice', NOW())
('programming', 'bob', NOW())
('programming', 'charlie', NOW())

('learn', 'alice', NOW())
('learn', 'bob', NOW())
('learn', 'charlie', NOW())

Jika properti yang sama diulang beberapa kali, Firestore dalam mode Datastore dapat mendeteksi exploding index dan menyarankan indeks alternatif. Namun, dalam semua kasus lainnya (seperti kueri yang ditentukan dalam contoh ini), database mode Datastore akan menghasilkan exploding index. Dalam kasus ini, Anda dapat menghindari exploding index dengan mengonfigurasi indeks secara manual dalam file konfigurasi indeks:

indexes:
- kind: Task
  properties:
  - name: tags
  - name: created
- kind: Task
  properties:
  - name: collaborators
  - name: created

Tindakan ini mengurangi jumlah entri yang diperlukan menjadi hanya (|tags| * |created| + |collaborators| * |created|), atau 6 entri, bukan 9:

('fun', NOW())
('programming', NOW())
('learn', NOW())

('alice', NOW())
('bob', NOW())
('charlie', NOW())

Setiap operasi commit yang akan menyebabkan indeks melebihi entri indeks atau batas ukuran akan gagal. Teks error menjelaskan batas yang terlampaui ("Too many indexed properties" atau "Index entries too large") dan indeks kustom mana yang menyebabkannya. Jika Anda membuat indeks baru yang akan melebihi batas entity apa pun saat dibuat, kueri terhadap indeks tersebut akan gagal dan indeks akan muncul dalam status Error di konsol Google Cloud. Untuk menangani indeks Error tersebut,

  1. Hapus indeks dari file konfigurasi indeks (index.yaml).
  2. Dengan menggunakan Google Cloud CLI, hapus indeks dari database menggunakan perintah datastore indexes cleanup, seperti yang dijelaskan dalam Menghapus indeks yang tidak digunakan.
  3. Salah satu
    • merumuskan kembali definisi indeks dan kueri yang sesuai, atau
    • menghapus entity yang menyebabkan exploding index.
  4. Tambahkan kembali indeks ke index.yaml.
  5. Dengan menggunakan Google Cloud CLI, tambahkan indeks ke database dengan menjalankan perintah datastore indexes create, seperti yang dijelaskan dalam Memperbarui Indeks.

Anda dapat menghindari exploding index dengan menghindari kueri yang memerlukan indeks kustom menggunakan properti daftar. Seperti yang dijelaskan sebelumnya, ini mencakup kueri dengan beberapa tata urutan atau kueri dengan campuran filter kesetaraan dan ketidaksetaraan.

Indeks untuk proyeksi

Kueri proyeksi mengharuskan semua properti yang ditentukan dalam proyeksi untuk disertakan dalam indeks. Emulator Datastore 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 priority, percent_complete FROM Task

SELECT priority, percent_complete, created FROM Task

Namun, jika Anda selalu memproyeksikan properti priority, percent_complete, created, meskipun created 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 Task
WHERE priority > 1
ORDER BY priority, percent_complete

yang memerlukan indeks:

indexes:
- kind: Task
  properties:
  - name: priority
  - name: percent_complete

Mengonversi ini ke salah satu kueri proyeksi

SELECT created FROM Task
WHERE priority > 1
ORDER BY priority, percent_complete

SELECT priority, percent_complete, created FROM Task
WHERE priority > 1
ORDER BY priority, percent_complete

memperkenalkan properti baru (created) sehingga akan memerlukan pembuatan indeks baru:

indexes:
- kind: Task
  properties:
  - name: priority
  - name: percent_complete
  - name: created

Namun,

SELECT priority, percent_complete FROM Task
WHERE priority > 1
ORDER BY priority, percent_complete

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

Beberapa database

Anda dapat menggunakan gcloud firestore untuk mengelola satu indeks untuk mode Datastore atau menggunakan gcloud datastore dengan file index.yaml untuk mengelola semua indeks dalam database.

gcloud firestore
gcloud firestore indexes composite create --api-scope=datastore-mode-api  --query-scope=QUERY_SCOPE --database=DATABASE_ID
datastore gcloud
gcloud alpha datastore indexes create index.yaml --database=DATABASE_ID

Ganti kode berikut:

  • DATABASE_ID: ID database.
  • QUERY_SCOPE: collection-recursive untuk indeks ancestor atau collection-group untuk indeks non-ancestor.