2013-12-22 19 views
6

Nehmen wir an, wir speichern Autos (ca. 40MB) als JSON-Objekte in einer PouchDB dargestellt, und wir würden gerne suchen, basierend auf dem PS-Attribut. Beispiel in sql: Wählen * aus Autos, wo HP> 100.PouchDB Abfrage mit Parametern

Sie können PouchDB nach Schlüssel abfragen, aber offensichtlich ist HP nicht der Schlüssel des Dokuments. Gibt es eine Möglichkeit, dies zu tun?

Soweit ich die Kartenfunktion, verstehen

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

es ist nicht möglich, jede Variable innerhalb des äußeren Umfangs der Funktion zuzugreifen.

var horsePower = $scope.horsePowerInputField 

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

Gibt es eine Möglichkeit, die Datenbank, basierend auf Nicht-Schlüsselvariablen parametrisiert?

Antwort

3

Ihre map-Funktion verliert ihre Schließung, weil sie innerhalb von PouchDB neu ausgewertet wird (so erhält sie die emit-Funktion). Dies bedeutet, dass Sie aus Ihrem Code nicht auf Variablen zugreifen können, aber Sie können die Datenbank trotzdem abfragen.

In PouchDB sind Ansichten nicht persistent, so dass Ihre Abfrage immer jedes Dokument in der Datenbank betrachtet, und Sie die Filterfunktion nach der Kartenfunktion durchführen müssen. Etwas wie dieses:

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

Ist eine Weise, dieses Problem zu lösen. Pouch wird über jedes Dokument iterieren und es an Ihre map-Funktion übergeben. Wenn Sie fertig sind, wird filter mit einem Array aller ausgegebenen Dokumente aufgerufen. filter verliert seinen Schließkontext nicht, so dass Sie hier die Ergebnisse nach Pferdestärken oder anderen Feldern filtern können.

0

können Sie eine globale 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); 
      }); 

     } 
    }) 
    }; 

verwenden und die Art und Weise Sie es sind

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

8

Ab PouchDB 2.0.0, Schließungen in der Karte/reduzieren Abfragen unterstützt nennen ist. Details here.

Allerdings sollten Sie sie wahrscheinlich vermeiden, wenn Sie können, weil

  1. Sie sind nicht von CouchDB unterstützt, nur PouchDB
  2. Saved map/reduce views, die viel schneller sind und werden wahrscheinlich in 2.1.0 hinzugefügt werden , kann Schließungen nicht unterstützen.

aber sagen, dass, wenn Sie Verschlüsse verwenden wollen, können Sie dies jetzt tun:

var horsePower = $scope.horsePowerInputField 

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

Es ist besser, nicht Verschlüsse zu verwenden. Tun Sie dies stattdessen:

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