Можно ли написать запрос в ydn-db, аналогичный SQL-выражению IN, или нескольким предложениям AND?
Я пытаюсь написать запрос, который в 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 ответ
В настоящее время множественные запросы ("IN') и самостоятельное соединение ("AND") выполняются вручную и требуют для этого большого количества шаблонов. Для сложных запросов, как в этом случае, потребуется сортировка в памяти с использованием 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);
});