6

假设我们将汽车(大约 40MB)存储为 PouchDB 中的 JSON 对象,并且我们希望根据马力属性进行搜索。sql 中的示例:从 HP > 100 的汽车中选择 *。

可以key查询pouchDB,但是显然HP不是文档的key。有没有办法做到这一点?

据我了解地图功能,

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

无法访问函数外部范围内的任何变量。

var horsePower = $scope.horsePowerInputField

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

那么是否有可能查询基于非关键变量参数化的数据库?

4

4 回答 4

8

PouchDB 2.0.0开始,支持 map/reduce 查询中的闭包。 详情在这里

但是,如果可以的话,你应该避免它们,因为

  1. CouchDB 不支持它们,只有 PouchDB
  2. 保存的 map/reduce 视图速度更快,可能会在 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);
  }
}
于 2014-03-21T21:12:10.323 回答
3

您的map函数失去了它的关闭,因为它在 PouchDB 内部被重新评估(这就是它获取emit函数的方式)。这意味着您无法从代码中访问任何变量,但您仍然可以查询数据库。

在 PouchDB 中,视图不是持久的,因此您的查询总是查看数据库中的每个文档,并且您必须在 map 函数之后进行过滤。像这样的东西:

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

是解决这个问题的一种方法。Pouch 将遍历每个文档,并将其传递给您的map函数。完成后,filter使用包含所有已发出文档的数组调用。filter不会丢失其关闭上下文,因此您可以在此处根据马力或任何其他字段过滤结果。

于 2013-12-23T19:21:10.293 回答
1

最好不要使用闭包。改为这样做:

var horsePower = $scope.horsePowerInputField;
db.query(function(doc) {emit(doc.hp)}, {startkey: horsePower, include_docs: true});
于 2014-10-28T20:10:46.843 回答
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');

于 2014-02-25T23:20:47.260 回答