【问题标题】:Is it possible to write a query in ydn-db similar to a SQL "IN" or multiple "AND" clauses?是否可以在 ydn-db 中编写类似于 SQL“IN”或多个“AND”子句的查询?
【发布时间】:2014-10-30 06:37:18
【问题描述】:

我正在尝试编写一个在 SQL 中看起来像这样的查询:

select * from WorkOrder wo
    where wo.userId = 1
    and wo.isSynced = 0
    and wo.status in ('COMPLETE', 'REJECTED', 'SUSPENDED_NO_ACCESS', 'SUSPENDED_OTHER');

我在 userId、isSynced 和 status 上添加了一个索引。

如果我构建如下查询,只要我只过滤 2 个不同的状态值,它就可以工作。只要我添加 3 个或更多,它就不会返回任何结果。我做错了什么还是需要以完全不同的方式解决这个问题?

//this works
var keyRange = ydn.db.KeyRange.bound([userId, 0, Status.Complete],
            [userId, 0, Status.REJECTED]);
//this doesn't work
var keyRange = ydn.db.KeyRange.bound([userId, 0, Status.Complete],
            [userId, 0, Status.Suspended_AccessUnavailable],
            [userId, 0, Status.REJECTED]);


var iterator = new ydn.db.IndexValueIterator(Store.WorkOrder, 'userId, isSynced, status', keyRange);

return db.values(iterator)

【问题讨论】:

    标签: indexeddb ydn-db


    【解决方案1】:

    目前,多查询(“IN”)和自连接(“AND”)是手动的,需要大量样板文件才能完成。对于这种情况下的复杂查询,需要使用 @987654321 进行内存排序@。

    使用sorted merge or zigzag merge 进行自我加入。

    使用多个游标进行多查询。简述如下:

    var iters = [];
    var keys = ['COMPLETE', 'REJECTED', 'SUSPENDED_NO_ACCESS', 'SUSPENDED_OTHER'];
    for (var i = 0; i < keys.length; i++) {
      iters[i] = ydn.db.IndexValueIterator.where('WorkOrder', 'status', '=', keys[i]);
    });
    var results = [];
    db.scan(function(cursors) {
       // here we have four cursors for respective four index keys.
       // calculate lowest key(s) and put into result
       var min_i = ...
       results.push(cursors[i].getValue());
       // prepare next cursor iteration, 
       var next_position = [];
       next_position[min_i] = true; // advance lowest cursor to next position, while keeping the rest of cursor hold in current position.
       return next_position;
    }, iters, 'readonly', ['WorkOrder']).then(function() {
       // use results
       console.log('results', results);
    }, function(e) {
       console.error(e.stack);
    });
    

    为上面的代码做一个包装器并不难,这样库最终将支持如下:

     var query = db.from('WorkOrder').where('status', 'in', ['COMPLETE', 'REJECTED', 'SUSPENDED_NO_ACCESS', 'SUSPENDED_OTHER']);
     query.list().then(function() {
       // use results
       console.log('results', results);
    }, function(e) {
       console.error(e.message);
    });
    

    【讨论】:

    • 感谢您的回复。老实说,我并没有完全理解,所以我只是执行了多个查询,然后将结果合并到内存中。
    • 对不起,我的意思是……但这是 no-sql 数据库的典型问题吗?我根本不认为这是一个复杂的查询......如果我直接使用 IndexedDb 而不是通过包装库,这可能吗?
    猜你喜欢
    • 1970-01-01
    • 2017-12-04
    • 1970-01-01
    • 2018-05-27
    • 1970-01-01
    • 1970-01-01
    • 2015-07-19
    • 2016-05-04
    • 1970-01-01
    相关资源
    最近更新 更多