10

我在 indexeddb 对象存储上有两个属性的复合索引,并希望根据这两个属性的范围检索游标。

这是商店中的一个示例对象:

{species: 'Oak',xcoord: 123456, ycoord: 654321}

和索引:

treeStore.createIndex("treelocation", ["xcoord","ycoord"], { unique: false });

索引创建成功,我可以在 Chrome 开发人员工具中看到它,但是现在我想在 x 和 y 坐标(这将是地图的范围)上打开一个带有键范围的光标。

在线搜索我看不到如何做到这一点,并且打开带有键范围数组的索引似乎不起作用。

4

3 回答 3

7

范围建议是答案的一部分,但即使使用数组键,它实际上也只是一维范围,而不是数据的 2 维(或 N 维)选择。使用您当前的架构,您需要执行以下操作:

index.openCursor([lowX, lowY], [highX, highY]).onsuccess = function(e) {
    var cursor = e.target.result;
    if (!cursor) return; // done!

    var x = cursor.key[0], y = cursor.key[1];
    // assert(lowX <= x && x <= highX);
    if (y < lowY) {
        cursor.continue([x, lowY]);
    } else if (y > highY) {
        cursor.continue([x + 1, lowY]);
    } else {
        processRecord(cursor.value); // we got one!
        cursor.continue();
    }
};

(如果坐标不是整数,则替换+ 1为适当的 epsilon)

我已经发布了一个通用解决方案的示例:

https://gist.github.com/inexorabletash/704e9688f99ac12dd336

于 2015-10-06T17:51:01.383 回答
6

有人告诉我解决方案确实是IDBKeyRange.bound([lowX,lowY],[highX,highY]).

于 2013-05-14T10:06:50.597 回答
4

您创建的索引是复合索引。它是这样的查询:

index = objectStore.index('treelocation');
index.get([123456, 654321]); 

或者,您可以为每个坐标使用两个索引。在我看来,它更好。

x_index = objectStore.index('xcoord'); 
y_index = objectStore.index('ycoord');
x_species = x_index.get(IDBKeyRange.only(123456)) 
y_species = y_index.get(IDBKeyRange.only(654321)) 
species = x_species.intersect(y_species); // this is result
于 2013-05-13T23:32:25.363 回答