YDN-DB - 使用SortedMerge的混合数据类型的结果不正确

时间:2014-03-12 10:04:03

标签: indexeddb ydn-db

我正在使用优秀的YDN-DB作为复杂的“仪表板”网页的一部分,该网页允许用户下载大量信息然后搜索&过滤数据的方式。

数据以1 UNID和6列可见数据​​的形式出现,我使用这样的YDN架构存储:

var schema = {
    stores: [
        {
            name: 'test', keyPath: 'unid', autoIncrement: false,
            indexes: [
                {keyPath: 'a', type: 'TEXT'},
                {keyPath: 'b', type: 'TEXT'},
                {keyPath: 'c', type: 'TEXT'},
                {keyPath: 'd', type: 'DATE'},
                {keyPath: 'e', type: 'TEXT'},
                {keyPath: 'f', type: 'TEXT'}
            ]
        }
    ]
};

然后,用户可以在上面的六列中的任何一列上放置过滤器。构建过滤器的代码如下所示,并使用YDN KeyRange按用户请求的值过滤数据。

var filterArr = []
var resultArr = [];

filterArr.push(new ydn.db.IndexIterator('test', 'a', ydn.db.KeyRange.only('search value 1')));
filterArr.push(new ydn.db.IndexIterator('test', 'b', ydn.db.KeyRange.only('search value 2')));
.. [Continue adding filters for more columns if necessary etc] ..

var req = db.scan(new ydn.db.algo.SortedMerge(resultArr), filterArr);

req.then(function() {
    db.values('test', resultArr).done(function(results) {
        .. [Display code goes here] ..
    })
})

所以对于匹配的值,这很好。我的问题是,用户可以指定D列的日期范围,所以我更改了上面的一个filterArr行:

filterArr.push(new ydn.db.IndexIterator('test', 'd', ydn.db.KeyRange.bound(1389571200000, 1390435200000, false, false)));

这会导致搜索结果不正确。它似乎只在指定了多个filterArr值时才会发生。如果我自己过滤D列,它似乎可以工作。

很抱歉复杂的查询,真的希望得到某种答案。我花了一些时间调试SortedMerge JS,我的有限知识表明每次调用ydn.db.cmp函数的结果都出错了,所以我想知道这是否是YDN DB中的错误?

2 个答案:

答案 0 :(得分:1)

从我可以看到的代码中,列'd'应该是INTEGER,或者查询应该使用如下日期:

ydn.db.KeyRange.bound(toDate(1389571200000),toDate(1390435200000), false, false)

编辑:

抱歉,密钥加入算法仅适用于equi-join。范围不起作用。但是,您可以使用一个范围查询,但需要六个复合索引[a,d],[b,d],[c,d],d,[e,d],[f,d]并使用ZigZeg合并进行连接。详情http://dev.yathit.com/ydn-db/nosql-query.html您还可以找到equi join的要求。

当前ZigZeg比SortedMerge快,因为IndexedDB API规范1没有require方法。然而,v2将带有require方法,即openKeyCursorcontinuePrimaryKey。 ZigZeg的结果按d排序,而SortedMerge按主键排序。

答案 1 :(得分:0)

而不是存储Date对象,而是存储时间戳表示:

var timestamp = new Date().getTime();

由于时间戳是一个整数,因此您可以有效地使用它上的键范围。