我有一个文件对象存储索引 name and library_id
如下图所示,
let objectStore = db.createObjectStore('file', { keyPath: 'id' });
tempStore.createIndex('nameLibId', ['attributes.name', 'attributes.library_id'], { unique: false });
对象存储包含多个库id的文件。我想将名称排序应用于特定库id的文件。我尝试了以下格式的索引,但它返回空数据。
let self = this,
db = get(self, 'db'),
transaction = db.transaction(["file"], "readonly"),
objectStore = transaction.objectStore("file"),
index = objectStore.index('nameLibId'),
keyRange = IDBKeyRange.only('library_id')),
req = index.getAll(keyRange);
req.onsuccess = ((e)=>{
console.log(e.target.result); // returns empty array
});
附db模型截图供参考。24536475
, `` , created
, jhgf
以及 lastmodified
文件名属于名为 123
. Screen Shot..*
文件名属于另一个名为 234
.
我需要的文件是按名称排序,只有给定的图书馆id。任何帮助将不胜感激。
1条答案
按热度按时间r7knjye21#
如果您的索引基于属性数组,并且希望使用
IDBKeyRange.only
,然后将参数IDBKeyRange.only
也应该是数组。现在比较的是基本字符串值和属性数组值,当然没有匹配的。换句话说,不能仅使用两部分数组的一部分来查询它。此外,idbkeyrange.only的参数不是属性名,而是一个值。您想在索引的键路径值集中指定一个要匹配的值。例如,如果索引完全基于attributes.name,则需要在该索引中指定一个特定值,例如“”。
因此,考虑到以上两点,并且假设您的索引不是一个单一的值,而是一个由两个属性组成的数组,您需要将参数修改为idbkeyrange.only以查找数组。像这样的
IDBKeyRange.only(['', 'yoktc....']);
.现在,由于您在代码中所做的事情实际上并没有实现您想要的目标,这就更加复杂了。暂时忽略排序问题,在匹配此索引的行时,只希望使用id条件,而不希望使用名称。所以你可能想试试
IDBKeyRange.only([undefined, 'asdf'])
. 不幸的是,这根本不起作用,因为您不能指定undefined(您将得到一个javascript错误)。因此,您必须始终按两个值进行查询,即使您只想对其中一个值应用条件。这里的诀窍是,您可以切换到使用不同的方法,而不仅仅是。你用
IDBKeyRange.bound()
,而且,你还做了一个技巧,指定了一个条件,比如“最小可能数小于我的数,而我的数小于最大可能数”,比如一个总是为真的条件。你使用“最小可能值”作为你的下边界,“最大可能值”作为你的上边界。这是你的例子。我认为name的最小可能值是空字符串。name的最大可能值可能是任何非字母数字字符,所以让我们使用颚化符“~”。现在我们重写range参数。我们不使用idbkeyrange.only,而是使用idbkeyrange.bound。大致如下所示:
现在是第二部分,关于排序,以及使用包含多个部分的索引的主要注意事项(不要与multipart index属性相混淆,ugh)。我自己也一直在倒过来,所以我甚至可能错了,上面的方法也会奏效。上面的问题是,第一个标准被满足,第二个标准被忽略,因为短路数组排序算法在indexeddb的比较函数中是如何工作的。您的查询将匹配所有内容,因为每个索引行都符合条件。所以实现这个的诀窍是总是首先按重要条件进行查询,基本上要注意指定条件的顺序。因此,这意味着您需要在创建索引时切换指定属性的顺序,以便可以先按libid查询,然后按名称查询。
而不是
createIndex('nameLibId',['attributes.name','attributes.library_id']);
你想做什么createIndex('nameLibId',['attributes.library_id', 'attributes.name']);
. 这也意味着您需要交换上下限查询,例如。var lowerBound = [libId, smallestNameValue];
(别忘了换鞋面)。正如我在关于使用复合索引的回答中提到的,您可以始终使用
indexedDB.cmp
做实验。现在,打开此网页上的控制台。在控制台中,键入如下内容:看看结果。
最后的一些注意事项:
tilde可能是使用错误的东西,对不起,我不想麻烦记住,您也可以尝试任何有效的sentinel值,其中sentinel是指您知道的任何值总是在所有其他有效值之后
正如我在另一个答案中指出的,如果数据中缺少任何一个道具,那么实际对象将不匹配
对于cmp,-1表示左小于右,0表示左等于右,1表示左大于右