1

我将出色的 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 中的错误?

4

2 回答 2

1

从你的代码中我可以看到,列“d”应该是整数,或者查询应该使用日期,如:

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

编辑:

抱歉,密钥加入算法仅适用于等值加入。范围将不起作用。但是,您可以使用一个范围查询,但需要六个复合索引 [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 方法,即openKeyCursorand continuePrimaryKey。ZigZeg 的结果按 d 排序,而 SortedMerge 则按主键排序。

于 2014-03-12T12:49:30.463 回答
0

与其存储Date对象,不如存储时间戳表示:

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

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

于 2014-03-14T17:35:33.277 回答