Javascript 使用多个条件查询

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6405650/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 21:34:27  来源:igfitidea点击:

Query using multiple conditions

javascriptindexeddb

提问by jthereliable

I recently discovered (sadly) that WebSQL is no longer being supported for HTML5 and that IndexedDB will be replacing it instead.

我最近(遗憾地)发现 HTML5 不再支持 WebSQL,IndexedDB 将取而代之。

I'm wondering if there is any way to query or search through the entries of an IndexedDB in a similar way to how I can use SQL to search for an entry satisfying multiple conditions.

我想知道是否有任何方法可以以类似于如何使用 SQL 搜索满足多个条件的条目的方式来查询或搜索 IndexedDB 的条目。

I've seen that I can search through IndexedDB using one condition with the KeyRange. However, I can't seem to find any way to search two or more columns of data without grabbing all the data from the database and doing it with for loops.

我已经看到我可以使用 KeyRange 的一个条件来搜索 IndexedDB。但是,如果不从数据库中获取所有数据并使用 for 循环进行搜索,我似乎找不到任何方法来搜索两列或更多列数据。

I know this is a new feature that's barely implemented in the browsers, but I have a project that I'm starting and I'm researching the different ways I could do it.

我知道这是一个几乎没有在浏览器中实现的新功能,但我有一个我正在启动的项目,我正在研究我可以使用的不同方法。

Thank you!

谢谢!

采纳答案by Josh

Check out this answerto the same question. It is more detailed than the answer I give here. The keypath parameter to store.createIndex and IDBKeyRange methods can be an array. So, crude example:

看看这个对同一问题的回答。它比我在这里给出的答案更详细。store.createIndex 和 IDBKeyRange 方法的 keypath 参数可以是一个数组。所以,粗略的例子:

// 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]));

回答by Josh

Let's say your SQL Query is something like:

假设您的 SQL 查询类似于:

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

Equivalent Query in JsStorelibrary:

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

Now, if you are wondering what JsStore is, let me tell you it is a library to query IndexedDB in a simplified manner. Click hereto learn more about JsStore

现在,如果您想知道 JsStore 是什么,让我告诉您它是一个以简化方式查询 IndexedDB 的库。单击此处了解有关JsStore 的更多信息

回答by Kevin

I'm a couple of years late, but I'd just like to point out that Josh's answer works on the presumption that all of the "columns" in the condition are part of the index's keyPath.

我迟到了几年,但我只想指出,Josh 的答案是基于条件中的所有“列”都是索引的keyPath.

If any of said "columns" exist outside the the index's keyPath, you will have to test the conditions involving them on each entry which the cursor created in the example iterates over. So if you're dealing with such queries, or your index isn't unique, be prepared to write some iteration code!

如果任何上述“列”存在于索引之外keyPath,您将必须在示例中创建的游标迭代的每个条目上测试涉及它们的条件。因此,如果您正在处理此类查询,或者您的索引不是unique,请准备好编写一些迭代代码!

In any case, I suggest you check out BakedGoodsif you can represent your query as a boolean expression.

无论如何,如果您可以将查询表示为布尔表达式,我建议您查看BakedGoods

For these types of operations, it will always open a cursor on the focal objectStore unless you're performing a strict equality query (x ===? y, given x is an objectStore or index key), but it will save you the trouble writing your own cursor iteration code:

对于这些类型的操作,除非您执行严格的相等查询(x ===? y,给定 x 是 objectStore 或索引键),否则它将始终在焦点 objectStore 上打开一个游标,但它会为您省去编写自己的游标迭代代码的麻烦:

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

Just for the sake of complete transparency, BakedGoods is maintained by moi.

只是为了完全透明,BakedGoods 由moi维护。

回答by Matt Browne

I mention some suggestions for querying relationships in my answer to this question, which may be of interest:

我在我对这个问题的回答中提到了一些查询关系的建议,这些建议可能很有趣:

Conceptual problems with IndexedDB (relationships etc.)

IndexedDB 的概念问题(关系等)

As to querying multiple fields at once, it doesn't look like there's a native way to do that in IndexedDB (I could be wrong; I'm still new to it), but you could certainly create a helper function that used a separate cursor for each field, and iterated over them to see which records met all the criteria.

至于一次查询多个字段,在 IndexedDB 中似乎没有一种本地方式可以做到这一点(我可能是错的;我还是新手),但是您当然可以创建一个使用单独的辅助函数每个字段的光标,并遍历它们以查看哪些记录满足所有条件。

回答by Kyaw Tun

Yes, opening continuous key range on an index is pretty much that is in indexedDB. Testing for multiple condition is not possible in IndexedDB. It must be done on cursor loop.

是的,在索引上打开连续键范围几乎是在 indexedDB 中。在 IndexedDB 中无法测试多个条件。它必须在游标循环上完成。

If you find the solution, please let me know.

如果您找到解决方案,请告诉我。

BTW, i think looping cursor could be very fast and require less memory than possible with Sqlite.

顺便说一句,我认为循环游标可能非常快,并且比使用 Sqlite 需要更少的内存。