2013-12-22 6 views
6

Предположим, мы храним автомобили (около 40 МБ), представленные как объекты JSON в PouchDB, и мы хотели бы искать, основываясь на атрибуте лошадиной силы. пример в sql: выберите * из автомобилей, где HP> 100.Запрос PouchDB с использованием параметров

Вы можете запросить pouchDB ключом, но, очевидно, HP не является ключом документа. Есть ли способ, которым вы можете это сделать?

Насколько я понимаю функцию карты,

function(doc) { 
    if(doc.value) { 
    emit(doc.value, null); 
    } 
} 

не удается получить доступ к любой переменной в пределах внешней области видимости функции.

var horsePower = $scope.horsePowerInputField 

function(doc) { 
    if(doc.hp > horsePower) { 
    emit(doc.value, null); 
    } 
} 

так есть возможность запросить базу данных, параметризованную на основе неключевых переменных?

ответ

3

Функция map теряет свое закрытие, потому что она переоценивается внутри PouchDB (вот как она получает функцию emit). Это означает, что вы не можете получить доступ к каким-либо переменным из вашего кода, но вы все равно можете запросить базу данных.

В PouchDB представления не являются постоянными, поэтому ваш запрос всегда смотрит на каждый документ в базе данных, и вам необходимо выполнить фильтрацию после функции карты. Что-то вроде этого:

function findCars(horsePower, callback) { 
    // emit car documents 
    function map(doc) { 
    if(doc.type == 'car' && doc.value) { 
     emit(doc.value, null); 
    } 
    } 

    // filter results 
    function filter(err, response) { 
    if (err) return callback(err); 

    var matches = []; 
    response.rows.forEach(function(car) { 
     if (car.hp == horsePower) { 
     matches.push(car); 
     } 
    }); 
    callback(null, matches); 
    } 

    // kick off the PouchDB query with the map & filter functions above 
    db.query({map: map}, {reduce: false}, filter) 
} 

Это один из способов решить эту проблему. Чехол будет перебирать каждый документ, передавая его функции map. Когда сделано, filter вызывается с массивом всех испущенных документов. filter не теряет контекст закрытия, поэтому вы можете фильтровать результаты на основе мощности или любой другой области здесь.

0

Вы можете использовать глобальную переменную трюк

var getTimesheetId = ''; //global Variable 
var getOfflineTimesheet= function(documentId){ 
getTimesheetId = documentId; // assigning the value of the parameter to the global variable 


var map= function(doc){ 
     if(doc.timesheet){ 
      console.log(getTimesheetId); // here the map function is able to get the value of the global variable, which is essentially the parameter. 
      if (doc._id == getTimesheetId){ 
       emit(doc._id, doc.timesheet); 
      } 
     } 
    }; 

db.query({map: map}, function(err, res){ 
     if(!err){ 
      var out= ""; 
      res.rows.forEach(function(element){ 
       console.log(element.value); 
      }); 

     } 
    }) 
    }; 

И так, как вы будете называть это

getOfflineTimesheet('timesheet1DocId'); getOfflineTimesheet('timesheet2DocId'); getOfflineTimesheet('timesheet3DocId');

8

По PouchDB 2.0.0, закрытие на карте/уменьшить запросы поддерживаются. Details here.

Однако, вы, вероятно, следует избегать их, если вы можете, потому что

  1. Они не поддерживаются CouchDB, только PouchDB
  2. Saved map/reduce views, которые гораздо быстрее, и, вероятно, будет добавлен в 2.1.0 , не может поддерживать закрытие.

Это, как говорится, если вы хотите использовать замыкание, вы можете сделать это:

var horsePower = $scope.horsePowerInputField 

function(doc, emit) { // extra 'emit' tells PouchDB to allow closures 
    if(doc.hp > horsePower) { 
    emit(doc.value, null); 
    } 
} 
1

Это лучше не использовать замыкание. Вместо этого:

var horsePower = $scope.horsePowerInputField; 
db.query(function(doc) {emit(doc.hp)}, {startkey: horsePower, include_docs: true}); 
Смежные вопросы