2011-08-16 22 views
19

Ok, prima di tutto, mi dispiace per il mio inglese.IndexedDB Fuzzy Search

Sto lavorando a un progetto Web che indica quando digito qualcosa nella casella di input, ma desidero utilizzare IndexedDB per migliorare la velocità di query in Firefox.

Con WebSQL ho questa frase:

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 
    }); 
}); 

voglio fare stessa cosa con IndexedDB e ho questo codice:

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(); 
     } 
    } 
}; 

Ma c'è troppo lento e il mio codice è buggy .. Voglio sapere c'è un modo migliore per farlo.

Grazie per la risposta.

risposta

20

Ho finalmente trovato la soluzione a questo problema.

La soluzione consiste nel collegare un intervallo di chiavi tra il termine di ricerca e il termine di ricerca con una lettera 'z' nel finale. Esempio:

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(); 
    } 
    }; 

Perché ho bisogno di ordinare il risultato, così ho definito un array prima della transazione, allora noi lo chiamiamo quando abbiamo caricato tutti i dati, in questo modo:

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 
    } 
    }; 
+0

Grazie mille! Questo lo ha ridotto da 3500 ms a 140 ms per me. – pimvdb

+0

@pimvdb Buono a sapersi che l'hai trovato utile. Ho aggiunto qualche altro esempio sull'ordinamento del risultato. –

+6

Sarebbe meglio usare '\ uffff' come pugnale piuttosto che z. Non otterrai risultati di ricerca come "wikipædia" durante la ricerca di "wiki" se usi z ... –

3

Ho sperimentato con IndexedDB e l'ho trovato molto lento, a cui ho aggiunto la complessità della sua API e non sono sicuro che valga la pena utilizzarlo.

Dipende molto da quanti dati hai, ma potenzialmente varrebbe la pena effettuare la ricerca in memoria, e quindi puoi semplicemente effettuare il marshalling e smontare i dati da un qualche tipo di archivio, indicizzatoDB o localStorage più semplice.

+0

Bene, sembra che per Internet Explorer e Firefox devo usare una semplice XMLHttpRequest, perché XHR + PHP è ancora più veloce. Sarebbe bello vedere WebSQL come standard, perché in questo modo i client useranno le applicazioni web con velocità ed efficacia, inoltre il server salverà le risorse a lungo termine. –

1

Ho perso ~ 2 ore sullo stesso problema e ho trovato il vero problema.

Ecco la soluzione:

  • Sostituire IDBCursor.PREV da prev (è terribile, ma questa è la soluzione)

IDBCursor.PREV è sempre sotto controllo al momento su Chrome (26/02/2013)

+0

Beh, il problema che hai avuto non è lo stesso di quello che ho avuto. Il tuo problema è causato dalle modifiche alle nuove specifiche (aggiornate il 20 febbraio 2013): https://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html. PS: ho appena aggiornato il mio problema e la mia risposta per abbinare le nuove specifiche. –