IndexedDB 模糊搜索

Posted

技术标签:

【中文标题】IndexedDB 模糊搜索【英文标题】:IndexedDB Fuzzy Search 【发布时间】:2011-10-28 12:12:06 【问题描述】:

好的,首先,对不起我的英语。

我正在从事一个网络项目,当我在输入框中输入内容时会显示提示,但我想使用 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
    
  ;

【讨论】:

非常感谢!这对我来说从 3500 毫秒减少到了 140 毫秒。 @pimvdb 很高兴知道您发现它很有用。我添加了更多关于排序结果的示例。 最好使用\uffff 作为你的匕首而不是z。如果你使用z搜索“wiki”,你将不会得到类似“wikipædia”的搜索结果... 如何在搜索词的开头使用通配符?以下返回错误:IDBKeyRange.bound('\uffff' + searchTerm, searchTerm + '\uffff') @Hazaart 不幸的是,无法在搜索词的开头使用通配符。【参考方案2】:

我一直在试验 IndexedDB,发现它非常慢,再加上它的 api 的复杂性,我根本不确定它是否值得使用。

这实际上取决于您拥有多少数据,但可能值得在内存中进行搜索,然后您可以将数据从某种存储中编组和取消编组,无论是 indexedDB 还是更简单的本地存储。

【讨论】:

好吧,对于 Internet Explorer 和 Firefox,我似乎必须使用简单的 XMLHttpRequest,因为 XHR+php 更快。很高兴看到 WebSQL 成为标准,因为这样客户端将快速有效地使用 Web 应用程序,而且服务器将长期节省资源。【参考方案3】:

我在同一个问题上浪费了大约 2 个小时,我找到了真正的问题。

这里的解决方案:

IDBCursor.PREV 替换为prev (这很糟糕,但这是解决方案)

IDBCursor.PREV 目前在 Chrome 上被窃听(26/02/2013)

【讨论】:

嗯,你遇到的问题和我的不一样。您的问题是由新规范的更改引起的(2013 年 2 月 20 日更新):dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html。 PS:我刚刚更新了我的问题和答案以符合新规范。

以上是关于IndexedDB 模糊搜索的主要内容,如果未能解决你的问题,请参考以下文章

ES实现模糊搜索

C# combobox 模糊搜索。

关于Lucene怎么使用SpanQuery进行模糊搜索

mysql怎么实现全局的模糊搜索?

搜索框实现模糊查询方法 - js

vue实现模糊搜索