6

JSON オブジェクトとして表現された車 (約 40MB) を PouchDB に格納し、馬力属性に基づいて検索したいとします。SQL の例: select * from cars where HP > 100.

キーで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);
  }
}

非キー変数に基づいてパラメータ化されたデータベースにクエリを実行する可能性はありますか?

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

関数は、 PouchDBmap内で再評価されるため、クロージャーを失います (これが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)
}

この問題を解決する 1 つの方法です。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 に答える