Как получить все значения ключей IDBIndex (вместо первичных ключей хранилища объектов)? - PullRequest
0 голосов
/ 03 декабря 2018

У меня есть хранилище объектов IndexedDB с первичным ключом и дополнительным индексом (с ограничением уникального ключа).

Теперь я хочу получить все значения ключа этого индекса.

РанееЯ использовал IDBIndex.getAllKeys (), но, по-видимому, поведение этого метода изменилось, чтобы вернуть первичные ключи хранилища объектов вместо ключей индекса.(Однако я не могу найти какую-либо документацию или ссылку в примечаниях к выпуску браузера на этот счет ...)

Поэтому мой вопрос: каков рекомендуемый, наиболее эффективный способ получения всех значений ключа индекса?

Ответы [ 2 ]

0 голосов
/ 24 июня 2019

Знаете ли вы, почему существует метод IDBIndex.getAllKeys(), если он возвращает то же самое, что и IDBObjectStore.getAllKeys()

Одна из причин наличия этих двух отдельных методов заключается в том, что они оба принимаютнеобязательный аргумент query, который является диапазоном ключей.

В случае IDBObjectStore.getAllKeys(query) диапазон ключей является диапазоном первичных ключей , а результатом является массив первичные ключи

В случае IDBIndex.getAllKeys(query) диапазон ключей представляет собой диапазон индексных ключей , а в результате получается массив первичных ключей

Пример:

/* store (key = SSN) */
const users = await db.createObjectStore("users", { keyPath: "SSN" });

/* index (key = surname) */
users.createIndex("surname", "surname");

/* 1. get all SSNs from store */
const keys = await users.getAllKeys();

/* 2. get all SSNs starting between 'a' and 'f' */
const keys = await users.getAllKeys(IDBKeyRange.bound('a', 'f'));

/* 3. get all SSNs from index (same as #1) */
const keys = await users.index("surname").getAllKeys();

/* 4. get all SSNs where surname is between 'a' and 'f' (different to #2) */
const keys = await users.index("surname").getAllKeys(IDBKeyRange.bound('a', 'f'));
0 голосов
/ 04 декабря 2018

IDBIndex.getAll будет работать, но будет считывать все значения в память, что может быть медленным.

И вы правы, что IDBIndex.getAllKeys возвращает только первичные ключи, а не индексные ключи.

К сожалению, нет аналогичной единственной функции, которая будет возвращать индексные ключи, но вы можете использовать IDBIndex.openKeyCursor и избегать чтения значений в память:

const result = [];

index.openKeyCursor().onsuccess = (event) => {
    var cursor = event.target.result;
    if (cursor) {
        // cursor.key is the index key, cursor.primaryKey is the primary key,
        // and cursor.value is undefined because we're using openKeyCursor
        // rather than openCursor.
        result.push(cursor.key);
        cursor.continue();
    } else {
        cb(result);
    }
};

Я не тестировал это, нотеоретически это может быть почти так же быстро, как getAllKeys, хотя, вероятно, по крайней мере, несколько медленнее, потому что для этого нужно запускать и обрабатывать N событий, а не один.

Просто не пытайтесь сделать это в MS Edge:)

Ранее я использовал IDBIndex.getAllKeys (), но, по-видимому, поведение этого метода изменилось, чтобы возвращать первичные ключи хранилища объектов вместо ключей индекса.(Однако я не могу найти какую-либо документацию или ссылку в примечаниях к выпуску браузера на этот счет ...)

Если вы использовали indexeddb-getall-shim , более раннюю версиюВерсия ошибочно вернула ключи индекса, а не первичные ключи.Это никогда не было в спецификации, просто ошибка в прокладке.Так как я написал шим ... мои извинения, если это действительно источник вашего замешательства!

...