是否可以在ydn-db中编写类似于SQL“IN”或多个“AND”子句的查询?

时间:2014-09-05 10:19:04

标签: indexeddb ydn-db

我正在尝试编写一个在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)

1 个答案:

答案 0 :(得分:1)

目前多查询(“IN”)和自联接(“AND”)是手动的,需要大量的样板才能完成这些操作。对于像这种情况一样的复杂查询,需要使用{{进行内存排序3}}

使用ydn.structs.Buffer进行自我加入。

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

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);
});