1

時間値のあるレコードがあり、ある期間それらをクエリして、指定された間隔のレコードのみを返すことができる必要があります。

たとえば、12:00から1:00までのすべてのレコードが10分間隔で必要になる場合があり、12:00、12:10、12:20、12:30、... 12:50、01:00になります。間隔はパラメーターである必要があり、任意の時間値にすることができます。15分47秒1.4時間。

私はある種の削減を行ってこれを行おうとしましたが、それは明らかにそれを行うのに間違った場所です。

これが私が思いついたものです。コメントは大歓迎です。

時間フィールドのビューを作成して、時間の範囲を照会できるようにしました。ビューはIDと時刻を出力します。

function(doc) { 
  emit([doc.rec_id, doc.time], [doc._id, doc.time]) 
}

次に、intervalというパラメータを受け入れるリスト関数を作成しました。リスト関数では、行を調べて、現在の行の時刻を最後に受け入れられた時刻と比較します。スパンが間隔以上の場合は、行を出力に追加してJSON化します。

function(head, req) { 

  // default to 30000ms or 30 seconds.
  var interval = 30000; 

  // get the interval from the request.
  if (req.query.interval) {
    interval = req.query.interval; 
  }

  // setup
  var row; 
  var rows = []; 
  var lastTime = 0; 

  // go thru the results...
  while (row = getRow()) { 
      // if the time from view is more than the interval 
      // from our last time then add it.
      if (row.value[1] - lastTime > interval) { 
          lastTime = row.value[1]; 
          rows.push(row); 
      } 
  } 
  // JSON-ify!
  send(JSON.stringify({'rows' : rows}));
}

これまでのところ、これはうまく機能しています。いくつかの大きなデータに対してテストして、パフォーマンスがどのようになるかを確認します。これをどのように改善できるか、またはこれがソファでの正しい方法であるかについてのコメントはありますか?

4

1 に答える 1

1

CouchDBはリラックスしています。これがあなたのために働いているなら、私はそれに固執し、あなたの次の最優先事項に焦点を当てると思います。

簡単な最適化の1つは、_list関数に最終的な答えを作成するのではなく、send()ご存知のように答えのほんの一部を作成することです。そうすれば、関数を無制限の結果サイズで実行できます。

ただし、ご想像のとおり、_list基本的に関数を使用してアドホッククエリを実行しているため、データベースのサイズが大きくなると問題が発生する可能性があります。

何が必要かは100%わかりませんが、時間枠内でドキュメントを探している場合は、emit()キーが主に時間で並べ替えられる可能性があります。(この例では、プライマリ(左端)のソート値はdoc.rec_idです。)

マップ関数の場合:

function(doc) {
  var key = doc.time; // Just sort everything by timestamp.
  emit(key, [doc._id, doc.time]);
}

timeこれにより、タイムスタンプ順に並べられたすべてのドキュメントのマップが作成されます。(時間の値は、、JSON.stringify(new Date)つまりのようになると仮定します"2011-05-20T00:34:20.847Z"

1時間間隔ですべてのドキュメントを検索するには、を使用してマップビューにクエリを実行します?startkey="2011-05-20T00:00:00.000Z"&endkey="2011-05-20T01:00:00.000Z"

私があなたの「間隔」基準を正しく理解している場合、10分間隔が必要な場合、00:00、00:15、00:30、00:45、00:50の場合、00:00、00のみ:30、00:50が最終結果に含まれるはずです。したがって、通常のソファの出力をフィルタリングして、不要な結果を排除しています。それは関数にとって完璧な仕事です_list。間隔に一致する行req.query.intervalのみを使用するだけです。send()

于 2011-05-20T00:38:06.383 に答える