2011-06-19 95 views
24

我最近發現(遺憾的是)WebSQL不再支持HTML5,而IndexedDB將取而代之。如何在IndexedDB中使用多個條件進行查詢?

我想知道是否有任何方式來查詢或搜索索引數據庫的條目,類似於我如何使用SQL來搜索滿足多個條件的條目。

我見過我可以通過KeyRange使用一個條件搜索IndexedDB。但是,我似乎無法找到任何方法來搜索兩列或更多列數據,而無需從數據庫中獲取所有數據,並使用for循環執行。

我知道這是一個在瀏覽器中幾乎沒有實現的新功能,但我有一個項目,我正在開始研究不同的方式,我可以做到這一點。

謝謝!

+0

P.S.我嘗試使用LocalStorage並存儲JSON編碼的數組,並使用for循環對我的條件進行排序。但是,我的表是4000多個條目,循環遍歷所有這些條目需要超過(可能)100毫秒,這太長了。如果我使用IndexedDB,除非我可以進行多列查詢,否則我不會看到如何加快速度。 – jthereliable

+1

簡而言之:你需要[創建一個索引](http://www.w3.org/TR/IndexedDB/#widl-IDBObjectStore-createIndex)來查詢你想要的屬性,然後你抓住[index](http ://www.w3.org/TR/IndexedDB/#widl-IDBObjectStore-index),然後調用[openCursor](http://www.w3.org/TR/IndexedDB/#widl-IDBIndex- openCursor)方法。我可以拿出一個例子,但它可能需要我一天左右...... – robertc

+0

感謝您的迴應。我試圖做到這一點,但我無法找到如何查詢多行索引來執行諸如SQL的WHERE語句中的多列比較等操作。你有什麼建議嗎? – jthereliable

回答

25

查看this answer到同一個問題。這比我在這裏給出的答案更詳細。 store.createIndex和IDBKeyRange方法的keypath參數can be an array。因此,原油例如:

// In onupgradeneeded 
var store = db.createObjectStore('mystore'); 
store.createIndex('myindex', ['prop1','prop2'], {unique:false}); 

// In your query section 
var transaction = db.transaction('mystore','readonly'); 
var store = transaction.objectStore('mystore'); 
var index = store.index('myindex'); 
// Select only those records where prop1=value1 and prop2=value2 
var request = index.openCursor(IDBKeyRange.only([value1, value2])); 
// Select the first matching record 
var request = index.get(IDBKeyRange.only([value1, value2])); 
+1

createIndex方法的選項有第二個參數:multiEntry,它告訴indexedDB是否應該在數組中的每個元素或整個數組上創建索引。更多信息在這裏:http://www.w3.org/TR/IndexedDB/#widl-IDBObjectStore-createIndex-IDBIndex-DOMString-name-DOMString-sequence-DOMString--keyPath-IDBIndexParameters-optionalParameters –

0

我提一些建議,在我的答案查詢關係到這個問題,這可能會感興趣:

Conceptual problems with IndexedDB (relationships etc.)

至於一次查詢多個字段,它看起來並不像有一個本地在IndexedDB中做這件事的方法(我可能是錯的;我仍然對它不熟悉),但是你當然可以創建一個輔助函數,爲每個字段使用一個單獨的光標,並迭代它們以查看哪些記錄符合所有條件。

+0

感謝您的回答。是的,這幾乎是我所認爲的最好/唯一的解決方案。 – jthereliable

1

是的,在索引上打開連續的鍵範圍幾乎就是在indexedDB中。在IndexedDB中不可能測試多個條件。它必須在光標循環上完成。

如果您找到解決方案,請讓我知道。

順便說一句,我認爲循環遊標可能非常快,需要更少的內存比Sqlite可能。

+0

「如果您找到解決方案,請告訴我。」看起來喬希的答案是一個可行的解決方案。 – user3334690

1

我幾年晚了,但我只是想指出的是,約什的回答工程對推定在所有條件下的「列」是的一部分該指數的keyPath

如果任何上述「列」存在於索引的keyPath之外,那麼您將不得不在測試中創建的每個條目上涉及它們的條件進行迭代。所以如果你正在處理這樣的查詢,或者你的索引不是unique,準備寫一些迭代代碼!

無論如何,我建議你檢查出BakedGoods如果你可以表示你的查詢爲布爾表達式。

對於這些類型的操作,除非正在執行嚴格的相等查詢(x ===? y,假設x是objectStore或索引鍵),否則它將始終在焦點objectStore上打開遊標,但它會爲您節省寫入時的麻煩你自己的光標迭代代碼:

bakedGoods.getAll({ 
    filter: "keyObj > 5 && valueObj.someProperty !== 'someValue'", 
    storageTypes: ["indexedDB"], 
    complete: function(byStorageTypeResultDataObj, byStorageTypeErrorObj){} 
}); 

只是爲了完全透明的緣故,BakedGoods由MOI維持。

1

比方說,你的SQL查詢是一樣的東西:

SELECT * FROM TableName WHERE Column1 = 'value1' AND Column2 = 'value2' 

等效查詢中JsStore庫:

var Connection = new JsStore.Instance("YourDbName"); 
Connection.select({ 
    From: "YourTableName" 
    Where: { 
     Column1: 'value1', 
     Column2: 'value2' 
    }, 
    OnSuccess:function (results){ 
     console.log(results); 
    }, 
    OnError:function (error) { 
     console.log(error); 
    } 
}); 

現在,如果你想知道JsStore是什麼,讓我告訴你,這是一個庫以簡化的方式查詢IndexedDB。 Click here瞭解更多關於JsStore

相關問題