Удаление всех записей в хранилище объектов indexedDB для определенного значения индекса - PullRequest
2 голосов
/ 30 апреля 2019

Для хранилища объектов с ключом массива [a,b], где a также является индексом, существует ли более эффективный способ удаления всех записей для определенного значения a, чем открытие курсора на индексе a и удалить каждую запись как шаг через курсор?

Есть ли способ определить диапазон ключей только для индекса или просто на a и оставить b открытым для любого значения, чтобы можно было удалить все записи для этого диапазона ключей?

В данном конкретном случае a является положительным целым числом, исключающим ноль, а b является положительным целым числом, включающим ноль. Будет ли гарантировано, что диапазон ключей от [n, 0] до [n + 1,0] вернет все ключи, эквивалентные индексу a=n, независимо от значения b? Например, IDBKeyRange.bound ([2,0], [3,0], false, true) вернет все ключи для индекса a=2?

Приведенный выше диапазон ключей подходит для моих тестовых случаев, но я хотел бы знать, как справиться с ситуацией, если b не является целым числом, что делает его своего рода особым случаем.

Похоже, что следующее не будет работать, потому что он будет удалять только запись с key из 2. Есть ли такой метод для общего случая?

i = transaction.objectStore( name ).index( 'a' );
i.delete( 2 );

Спасибо.

Когда я узнал больше и посмотрел код, который генерирует желаемый результат, приведенный ниже, я больше не уверен, почему он работает. Ключ является составным [ topic, note ], а для k установлено только значение темы. Итак, ни один ключ в n не должен совпадать с k, не так ли?

Я не понимаю, почему n.openCursor( k ) вернул все записи для работы, поскольку ни у одной из них нет простого ключа. k рассматривается как ключ записей или значение индекса?

T = DB_open.base.transaction( ['notes'], 'readwrite' ),
o = T.objectStore( 'notes' ),
k = IDBKeyRange.only( topic_value );
n = T.objectStore( 'notes' ).index( 'topic' );

n.openCursor( k ).onsuccess = ( e ) =>  { /* stepped through cursor */ };

Похоже, что я не понял, что параметр key для индекса - это не ключ фактической записи, а ключ индекса, здесь значение темы. Для операций чтения и курсоров это прекрасно работает; но в индексе нет метода удаления, такого как deleteAll, эквивалентный getAll.

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

1 Ответ

0 голосов
/ 04 мая 2019

Похоже, что я не понял, что параметр key для индекса - это не ключ фактической записи, а ключ индекса, здесь значение темы.Для операций чтения и курсоров это прекрасно работает;но в индексе нет метода удаления, такого как deleteAll, эквивалентный getAll.

Вы правы, key - ключ индекса.И нет единой команды, чтобы сказать «удалить каждую запись, соответствующую определенному ключу или диапазону ключей в индексе». Вот некоторые обсуждения по этому поводу - моя интерпретация заключается в том, что нет существенного аргумента против существующей функциональности, но это достаточно редкий случай использования, который просто содержится в качестве невыполненного запроса функции.

Однако, если первичный ключ - это составной ключ, а первая запись в составном ключе - это поле, по которому вы хотите выполнить фильтрацию, вы можете использовать KeyRange и передать его в IDBObjectStore.delete, как вы предлагали:

В данном конкретном случае a является положительным целым числом, исключающим ноль, а b является положительным целым числом, включающим ноль.Можно ли гарантировать, что диапазон ключей от [n, 0] до [n + 1,0] вернет все ключи, эквивалентные индексу a=n, независимо от значения b?Например, IDBKeyRange.bound ([2,0], [3,0], false, true) вернет все ключи для индекса a=2?

Да, это будет работать.

Вы также можете поиграть с ним самим:

var range = IDBKeyRange.bound( [2,0], [3,0], false, true);
console.log(range.includes([2, -1])); // false
console.log(range.includes([2, 0])); // true
console.log(range.includes([2, 100])); // true
console.log(range.includes([2, Infinity])); // true
console.log(range.includes([3, 0])); // false

Просто для удовольствия ... вы также можете определить свой диапазон клавиш следующим образом:

var range = IDBKeyRange.bound( [2,0], [2,""], false, true);

так как числа сортируются перед строками.Есть множество других способов написать то же самое.Все сводится к тому, как сравнивать разные типы в спецификации IndexedDB.Как только у вас есть массивы или несколько типов, все становится интересным.

...