IndexedDB Нечеткий Поиск - PullRequest
       8

IndexedDB Нечеткий Поиск

22 голосов
/ 17 августа 2011

Хорошо, прежде всего, извините за мой английский.

Я работаю в веб-проекте, который предлагает подсказки при вводе чего-либо в поле ввода, но я хочу использовать 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();
        }
    }
};

Но это слишком медленно, и мой код содержит ошибки .. Я хочу знать, есть ли лучший способ сделать это.

Спасибо за ответ.

Ответы [ 3 ]

23 голосов
/ 22 января 2012

Я наконец нашел решение этой проблемы.

Решение состоит в том, чтобы связать ключевой диапазон между поисковым термином и поисковым термином буквой «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
    }
  };
3 голосов
/ 19 августа 2011

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

Это действительно зависит от того, сколько у вас данных, но, возможно, стоило бы выполнить поиск в памяти, и тогда вы можете просто маршалировать и демаршировать данные из какого-то хранилища, либо indexedDB, либо более простого LocalStorage.

1 голос
/ 26 февраля 2013

Я потерял ~ 2 часа из-за той же проблемы и нашел настоящую проблему.

Здесь решение:

  • Заменить IDBCursor.PREV на prev (этоужасно, но это решение)

IDBCursor.PREV прослушивается в данный момент в Chrome (26/02/2013)

...