html5 indexeddb 排序,html5 – 在IndexedDB中,有没有办法进行排序复合查询?
本回答中使用的术语“复合查询”是指在其WHERE子句中涉及多个条件的SQL SELECT语句。虽然indexedDB规范中没有提到这样的查询,但您可以通过创建一个包含一组属性名称的keypath的索引来近似复合查询的行为。
这与创建索引时使用多条目标志完全无关。多条目标志调整indexedDB如何在单个数组属性上创建索引。我们正在索引对象属性数组,而不是对象的单个数组属性的值。
创建索引
在此示例中,’name’,’gender’和’age’对应于存储在学生对象存储中的学生对象的属性名称。
// An example student object in the students store
var foo = {
'name': 'bar',
'age': 15,
'gender': 'M'
};
function myOnUpgradeNeeded(event) {
var db = event.target.result;
var students = db.createObjectStore('students');
var name = 'males25';
var keyPath = ['name', 'gender', 'age'];
students.createIndex(name, keyPath);
}
在索引上打开一个光标
然后可以在索引上打开一个光标:
var students = transaction.objectStore('students');
var index = students.index('males25');
var lowerBound = ['AAAAA','male',26];
var upperBound = ['ZZZZZ','male',200];
var range = IDBKeyRange.bound(lowerBound, upperBound);
var request = index.openCursor(range);
然而,由于我要解释的原因,这并不总是奏效。
另外:使用rangeCursor或get的range参数是可选的。如果不指定范围,则IDBKeyRange.only将被隐式使用。换句话说,您只需要为有界游标使用IDBKeyRange。
基本指标概念
指数就像对象商店,但不是直接可变的。而是在引用的对象存储上使用CRUD(创建读取更新删除)操作,然后,indexedDB会自动将更新级联到索引。
了解排序是理解指标的基础。索引基本上只是一个特别排序的对象集合。在技术上,它也被过滤,但我会在一会儿触及。通常,当您在索引上打开游标时,您将根据索引的顺序进行迭代。此顺序可能并且可能与引用对象存储中的对象的顺序不同。该顺序很重要,因为这样可以使迭代更有效率,并允许自定义的下限和上限在索引特定顺序的上下文中是有意义的。
索引中的对象在商店发生更改时排序。将对象添加到商店时,将其添加到索引中的正确位置。排序归结为一个比较函数,类似于Array.prototype.sort,它比较两个项目,并返回一个对象是否小于另一个,大于另一个对象或相等。因此,我们可以通过深入了解比较功能的更多细节来更好地理解排序行为。
字符串按字典顺序比较
这意味着,例如,’Z’小于’a’,字符串’10’大于字符串’020’。
使用规范定义的顺序比较不同类型的值
例如,该规范指定字符串类型值在日期类型值之前或之后。值不包含什么,只是类型。
IndexedDB不会为您强制类型。你可以在脚下射击自己。你通常不想比较不同的类型。
具有未定义属性的对象不会出现在其关键字由一个或多个这些属性组成的索引中
正如我所提到的,索引可能并不总是包括引用对象存储中的所有对象。将对象放入对象存储中时,如果索引所基于的属性缺少值,则对象将不会出现在索引中。例如,如果我们有一个我们不知道年龄的学生,并且我们将它插入学生商店,那么特定的学生不会出现在男性25的索引中。
记住这一点,当你想知道为什么在索引上迭代游标时不会出现一个对象。
还要注意null和空字符串之间的细微差别。空字符串不是缺少的值。具有空字符串的属性的对象仍然可以基于该属性出现在索引中,但如果属性存在但未定义或不存在,则该索引中不会出现该索引。如果它不在索引中,则在索引上迭代游标时,不会看到它。
创建IDBKeyRange时,必须指定数组keypath的每个属性
创建一个下限或上限时,必须为数组关键字中的每个属性指定一个有效值,以便在该范围上打开光标时在范围内使用。否则,您会收到一些类型的Javascript错误(因浏览器而异)。例如,您不能创建一个范围,例如IDBKeyRange.only([undefined,’male’,25]),因为name属性未定义。
令人困惑的是,如果你指定错误类型的值,例如IDBKeyRange.only([‘male’,25]),其中name是未定义的,你不会在上面的意义上得到错误,但是你会得到无意义的结果。
这个一般规则有一个例外:您可以比较不同长度的数组。因此,从技术上讲,您可以从范围中省略属性,前提是您从数组的末尾执行此操作,并适当地截断数组。例如,您可以使用IDBKeyRange.only([‘josh’,’male’])。
短路数组排序
将Array类型的值与Array的其他值进行比较,如下所示:
>令A为第一个数组值,B为第二个数组值。
>把长度作为A长度和B长度的较小者。
让我成为0。
>如果A的第i个值小于B的第i个值,则A较少
比B.跳过剩下的步骤。
>如果A的第i个值大于B的第i个值,则A大于B.跳过其余步骤。
>增加我1。
>如果我不等于长度,请返回到步骤4.否则继续下一步。
>如果A的长度小于B的长度,则A小于B.如果A的长度大于B的长度,则A大于B.否则A和B相等。
捕获在步骤4和5:跳过剩余的步骤。这基本上意味着如果我们比较两个数组用于顺序,例如[1,’Z’]和[0,’A’],则该方法仅考虑第一个元素,因为在该点1是>由于短路评估(规格中的步骤4和5),它永远不会检查Z对A。
所以,早期的例子是不会奏效的。它实际上更像如下:
WHERE (students.name >= 'AAAAA' && students.name <= 'ZZZZZ') ||
(students.name >= 'AAAAA' && students.name <= 'ZZZZZ' &&
students.gender >= 'male' && students.gender <= 'male') ||
(students.name >= 'AAAAA' && students.name <= 'ZZZZZ' &&
students.gender >= 'male' && students.gender <= 'male' &&
students.age >= 26 && students.age <= 200)
如果您在SQL或通用编程中有这样的布尔子句的任何经验,那么您已经应该认识到整套条件不一定涉及。这意味着您将无法获取所需的对象列表,这就是为什么您无法真正获得与SQL复合查询相同的行为。
处理短路
在当前的实现中,您不能轻易避免这种短路行为。在最坏的情况下,您必须将存储/索引中的所有对象加载到内存中,然后使用自己的自定义排序功能对集合进行排序。
有办法尽量减少或避免一些短路问题:
例如,如果您使用的是index.get(array)或index.openCursor(array),那么就没有任何短路问题。整场比赛还是整场比赛。在这种情况下,比较功能只是评估两个值是否相同,而不是一个是大于还是小于另一个。
其他技术要考虑:
>将关键字的元素从最窄到最大重新排列。基本上提供早期的夹具,可以切断一些不需要的短路结果。
>将包装的对象存储在使用特殊定制属性的商店中,以便可以使用非数组关键字(非复合索引)对其进行排序,或者可以使用不受短组合索引影响的复合索引,电路行为。
>使用多个索引。这导致了exploding index problem.注意这个链接是关于另一个no-sql数据库,但是相同的概念和解释适用于indexedDB,并且链接是一个合理(冗长和复杂的)解释,所以我不在这里重复。
> indexedDB(规范和Chrome实现)的创建者之一最近建议使用cursor.continue:https://gist.github.com/inexorabletash/704e9688f99ac12dd336
使用indexedDB.cmp进行测试
cmp function提供了一种快速简单的方法来检查排序是如何工作的。例如:
var a = ['Hello',1];
var b = ['World',2];
alert(indexedDB.cmp(a,b));
indexedDB.cmp函数的一个不错的属性是它的签名与Array.prototype.filter和Array.prototype.sort的函数参数相同。您可以轻松地从控制台测试值,而无需处理连接/ schemas /索引和所有这些。此外,indexedDB.cmp是同步的,所以您的测试代码不需要涉及async回调/承诺。
html5 indexeddb 排序,html5 – 在IndexedDB中,有没有办法进行排序复合查询?相关推荐
- pandas中dataframe索引排序实战:pandas中dataframe索引降序排序、pandas中dataframe索引升序排序
pandas中dataframe索引排序实战:pandas中dataframe索引降序排序.pandas中dataframe索引升序排序 目录
- python 按从小到大的顺序组合成一个字典_Python实现字典排序、按照list中字典的某个key排序的方法示例...
本文实例讲述了python实现字典排序.按照list中字典的某个key排序的方法.分享给大家供大家参考,具体如下: 1.给字典按照value按照从大到小排序 排序 dict = {'a':21, 'b ...
- java集合按大小排序_List集合对象中按照不同属性大小排序的实例
实例如下: package com.huad.luck; import java.util.arraylist; import java.util.collections; import java.u ...
- python中对列表排序_在Python中对嵌套列表进行排序和分组
在Python中对嵌套列表进行排序和分组 我具有以下数据结构(列表列表) [ ['4', '21', '1', '14', '2008-10-24 15:42:58'], ['3', '22', '4 ...
- es中java代码高亮显示_Elasticsearch实现复合查询,高亮结果等技巧
一.Es的配置 实现es的全文检索功能的第一步,首先从与es进行连接开始,这里我使用的是es的5.x java api语法. public TransportClient esClient() thr ...
- java实现什么接口进行排序_使用Java中Comparator接口实现自定义排序
一般情况下,自己动手写一个简单排序程序还是没有问题的,但是你能保证写出来的排序程序的时间复杂度吗?你能保证程序的正确性吗,鲁棒性呢,还有程序结构的清晰性,可维护性.......综上所述,学习一下排序接 ...
- python对日期型数据排序_在python中对日期字符串进行排序,最好不使用日期对象...
所以,我有一个字符串列表,这些字符串的格式都是Month DayNumber,比如 ['March 1', 'March 9', 'April 14', 'March 12'] 我需要对列表进行排序, ...
- python临时排序_python-在Django临时目录中对相关项目进行排序
是否可以在DJango模板中对一组相关项目进行排序? 也就是说:此代码(为清晰起见,省略了HTML标记): {% for event in eventsCollection %} {{ event.l ...
- java 两个字段排序,如何在Java中按两个字段排序?
I have array of objects person (int age; String name;). How can I sort this array alphabetically by ...
最新文章
- QT的QRegExpValidator类的使用
- 【clickhouse】clickhouse 主从配置 从节点无数据
- 衔着树枝飞跃太平洋的傻鸟!(童话版)
- Dynamics AX2012 弹出Message Box
- idea全局搜索快捷键总结
- 开心网游戏界面Html
- Cortex-M3 (NXP LPC1788)之ADC模/数转换器
- VBS教程--摘自百度百科
- 计算机派位录取,北京幼升小多校划片电脑派位是什么意思
- 开源数据库全接触-MongoDB,Cassandra,Hypertable,CouchDB,Redis,HBase,Voldemort等35款数据库简介
- 为什么工资高的程序员很少炫富?
- 生产车间问题频发如何解决?
- Cytoskeleton——SiR-肌动蛋白相关工具推荐
- 微信跨公众号进行支付
- [概念]CSV逗号分隔值
- 2023值得入手的小米电视推荐 小米75寸电视哪款性价比高?
- 企业托管服务器有什么优势
- 牛客练习赛51(C题 勾股定理)
- 《人民的名义》如何圈粉“90后”| 大数据舆情分析
- 标准生物钟作息时间表
热门文章
- cmd中Redis的启动
- sqlserver 微信 读取_Sql Server使用链接服务器远程取数据_sqlserver
- OFDM子载波频率 知乎_通过基于SDR的信号处理实现的低复杂度便携式无源无人机监控...
- 苹果php环境,苹果电脑安装PHP环境步骤-PHP问题
- CRITIC法之matlab
- python实例 99,100
- Python实例 61,62
- 径向基神经网络_谷歌开源Neural Tangents:5行代码打造无限宽神经网络模型,帮助“打开ML黑匣子”...
- 普通的java类型是指,String是一个很普通的类 - Java那些事儿
- Mysql的执行顺序与优化分析