Нечеткий поиск IndexedDB
Хорошо, прежде всего, извините за мой английский.
Я работаю в веб-проекте, который показывает, когда я ввожу что-то в поле ввода, но я хочу использовать IndexedDB для улучшения скорости запросов в Firefox.
В WebSQL у меня есть это предложение:
db.transaction(function (tx) {
var SQL = 'SELECT "column1",
"column2"
FROM "table"
WHERE "column1" LIKE ?
ORDER BY "sortcolumn" DESC
LIMIT 6';
tx.executeSql(SQL, [searchTerm + '%'], function(tx, rs) {
// Process code here
});
});
Я хочу сделать то же самое с IndexedDB, и у меня есть этот код:
db.transaction(['table'], 'readonly')
.objectStore('table')
.index('sortcolumn')
.openCursor(null, 'prev')
.onsuccess = function (e) {
e || (e = event);
var cursor = e.target.result;
if (cursor) {
if (cursor.value.column1.substr(0, searchTerm.length) == searchTerm) {
// Process code here
} else {
cursor.continue();
}
}
};
Но там слишком медленно, и мой код неисправен. Я хочу знать, есть ли лучший способ сделать это.
Спасибо за ответ.
Ответы
Ответ 1
Наконец, я нашел решение этой проблемы.
Решение состоит в том, чтобы связать диапазон ключей между поисковым термином и поисковым термином с буквой "z" в финале. Пример:
db.transaction(['table'], 'readonly')
.objectStore('table')
.openCursor(
IDBKeyRange.bound(searchTerm, searchTerm + '\uffff'), // The important part, thank Velmont to point out
'prev')
.onsuccess = function (e) {
e || (e = event);
var cursor = e.target.result;
if (cursor) {
// console.log(cursor.value.column1 + ' = ' + cursor.value.column2);
cursor.continue();
}
};
Поскольку мне нужно заказать результат, поэтому я определил массив перед транзакцией, затем мы вызываем его, когда мы загружаем все данные, например:
var result = [];
db.transaction(['table'], 'readonly')
.objectStore('table')
.openCursor(
IDBKeyRange.bound(searchTerm, searchTerm + '\uffff'), // The important part, thank Velmont to point out
'prev')
.onsuccess = function (e) {
e || (e = event);
var cursor = e.target.result;
if (cursor) {
result.push([cursor.value.column1, cursor.value.sortcolumn]);
cursor.continue();
} else {
if (result.length) {
result.sort(function (a, b) {
return a[1] - b[2];
});
}
// Process code here
}
};
Ответ 2
Я экспериментировал с IndexedDB, и я нашел его очень медленным, добавив к тому, что сложность его api и я не уверен, что его стоит использовать вообще.
Это действительно зависит от того, сколько данных у вас есть, но, возможно, стоит делать поиск в памяти, а затем вы можете просто сортировать и деактивировать данные из какого-то хранилища: indexedDB или более простого LocalStorage.
Ответ 3
Я потерял ~ 2 часа по одной и той же проблеме, и я нашел настоящую проблему.
Здесь решение:
- Заменить
IDBCursor.PREV
на prev
(это ужасно, но это решение).
IDBCursor.PREV
прослушивается в настоящий момент в Chrome (26/02/2013)