2

いくつかの理由で、couchdb内の50個のドキュメントごとにフェッチする必要があります。

たとえば、データベースには500人のユーザーがいて、最初、51番目、101番目....451番目のユーザーをフェッチしたいとします。

map / reduce関数を使用してこの結果を取得するにはどうすればよいですか?

(URLに「skip」パラメーターを設定して同様の動作を実行できることは知っていますが、map / reduceを使用して実行したいと思います)

ありがとう!

4

1 に答える 1

3

問題

覚えておくべき重要な点は、CouchDBのmap / reduceは似CREATE INDEX...ているということですが、そうではありませんSELECT * FROM...

Map / reduceは、行の静的リストを作成します。行は任意の順序にすることができます(発行するキーでソートされます)が、あるドキュメントが別のドキュメントの結果を変更することはできません。

この点を説明するために、このような行を持つ架空のビューがあるとします。キーはリスト内の「位置」であり、値はユーザー名です

// View rows (conceptual diagram only)
// Key, Value
0     , "mark" // Suppose Alice was created first, 1 week ago
1     , "bob"  // and Bob was created 1 day ago
2     , "evan" // and Evan was created 1 hour ago... so this view is chronological
... // etc.

これで、ボブのドキュメントにエラーがあったことがわかります。彼は実際には1日前ではなく、1年前にサインアップしました。彼のタイムスタンプを更新します。ビューは今どのように見えるべきですか?

// View rows (conceptual diagram only)
// Key, Value
0     , "bob"  // The corrected Bob document was created 1 **year** ago
1     , "mark" // ...and now Mark scoots down to the next position (!!!)
2     , "evan" // ...and Evan stayed the same
... // etc.

問題は次のとおりです。CouchDBでは、Bobのドキュメントのみを変更した場合、Markの行に影響を与えることはできません。それが基本的なアーキテクチャです。上記の(!!!)ラベルは、不可能な機能を示しています。問題は、最初の仮定です。つまり、相互の相対的な行の絶対位置を示すビューを持つことができます。( 「相対データベース」のように、相対という単語はリレーショナルと同じルートを持っていることに注意してください)

したがって、そのような技術は、帰謬法によって不可能です。

解決

map/reduceで必要なことのほとんどを行うことができます。キーとして仮想の位置の代わりに、キーとしてタイムスタンプを使用します。

// View rows (conceptual diagram only)
// Key, Value
2011-05-06, "bob"  // Bob signed up one year ago
2012-05-05, "mark" // Mark signed up one day ago
2012-05-06, "evan" // Evan one hour ago
... // etc.

もちろん、タイムスタンプの形式は明確な例を示すためのものです。おそらくISO8601形式(つまりJSON.stringify(new Date)、JavaScriptで取得したもの)を使用する必要があります。

サインアップを最新のものから取得するには、ビューに対して降順のクエリを実行します。行を1つだけ取得するには、オプションを使用しlimitます。

  • 最新のサインアップを取得するには:?descending=true&limit=1
  • 50番目に新しいものを入手するには:?descending=true&limit=1&skip=50
  • 100番目に新しいものを入手するには:?descending=true&limit=1&skip=100
于 2012-05-06T00:38:21.290 に答える