PouchDB request using parameters

Suppose we store cars (about 40 MB) that are represented as JSON objects in PouchDB, and we would like to search for them based on the horsepower attribute. example in sql: select * from cars where HP> 100.

You can query pouchDB by key, but obviously HP is not a document key. Is there any way to do this?

As far as I understand the map function,

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

it is impossible to access any variable in the outer scope of a function.

 var horsePower = $scope.horsePowerInputField function(doc) { if(doc.hp > horsePower) { emit(doc.value, null); } } 

is it possible to query a database parameterized based on non-key variables?

+6
source share
4 answers

PouchDB 2.0.0 supports closures in map / reduce requests. Details here .

However, perhaps you should avoid them if you can, because

  • They are not supported by CouchDB, only PouchDB
  • Saved maps / thumbnails that are much faster and likely to be added in 2.1.0 cannot support closure.

If you want to use closure, you can do this:

 var horsePower = $scope.horsePowerInputField function(doc, emit) { // extra 'emit' tells PouchDB to allow closures if(doc.hp > horsePower) { emit(doc.value, null); } } 
+8
source

The map function loses its closure because it is reevaluated inside PouchDB (the way it gets the emit function). This means that you cannot access any variables from your code, but you can still query the database.

In PouchDB, views are not permanent, so your query always looks at every document in the database, and you need to do filtering after the map function. Something like that:

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

This is one way to solve this problem. The cover will iterate over each document, passing it to the map function. When done, filter is called with an array of all emitted documents. filter does not lose the closing context, so you can filter the results based on power or any other field here.

+3
source

Better not to use closure. Do this instead:

 var horsePower = $scope.horsePowerInputField; db.query(function(doc) {emit(doc.hp)}, {startkey: horsePower, include_docs: true}); 
+1
source

You can use the global variable trick

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

And as you call him,

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

0
source

All Articles