web-dev-qa-db-ja.com

同じビューでのCouchDBのソートとフィルタリング

新しいアプリでCouchDBを使用しようとしています。複数のフィールドで並べ替え、複数のフィールドでフィルターするビューを作成する必要があります。ドキュメントの例を次に示します。_idと_revを省略して、入力の手間を省いています。

{
    "title": "My Document",
    "date": 1279816057,
    "ranking": 5,
    "category": "fun",
    "tags": [
        "couchdb",
        "technology"
    ],
}

ドキュメントから、ランキングなどのフィールドでソートするビューを簡単に作成できることがわかりました。

function(doc) {
    emit(doc.ranking, doc);
}

カテゴリなどのフィールドで簡単にフィルタリングできることも学びました

function(doc) {
    emit(doc.category, doc);
}

http://127.0.0.1:5984/database/_design/filter/_view/filter?key=%22fun%22

私の問題は、これらのことを同時にすべて行う必要があることです。カテゴリとタグに基づいてフィルタリングしたい。カテゴリが「fun」でタグが「couchdb」のドキュメントのみに絞り込むことができるはずです。フィルター処理された結果を降順で並べ替え、次に日付を昇順で並べ替え、次にタイトルをアルファベット順に並べ替えたい。

並べ替えとフィルタリングをすべて組み合わせた1つのビューを作成するにはどうすればよいですか?

33
Apreche

キーで複数のデータを放出するには、 Complex Keys を参照する必要があります。ほとんどの場合、カテゴリとタグで構成される配列であるキーをemit()することになります。例えば...

_function(doc) {
  for(var i = 0; i < doc.tags.length; i++)
    emit([doc.category, doc.tags[i]], doc);
}
_

ここで_?key=["fun", "couchdb"]_をクエリすると、「couchdb」でタグ付けされた楽しいカテゴリのすべてのアイテムが取得されます。または、タグに関係なく、楽しいカテゴリのすべてのアイテムが必要な場合は、_?startkey=["fun"]&endkey=["fun", {}]_の範囲でクエリできます。覚えておいてください。アイテムに複数のタグがある場合、結果に複数回表示されます(タグごとに1回ドキュメントをemit()したため)。

評価、日付、およびタイトルで並べ替えるという追加の手順に進むには、配列にさらに2つの要素を追加します。整数と、ランキング、日付、またはタイトルのいずれかです。マップ関数ごとに複数回emit()できることに注意してください。マップ関数の例...

_function(doc) {
  for(var i = 0; i < doc.tags.length; i++)
  {
     emit([doc.category, doc.tags[i], 0, doc.ranking], doc);
     emit([doc.category, doc.tags[i], 1, doc.title], doc);
     emit([doc.category, doc.tags[i], 2, doc.date], doc);
  }
}
_

今あなたのキー構造は次のとおりです:_["category", "tag", 0 ... 2, rank/title/date]_

基本的に、すべてのランキングを0未満、タイトルを1未満、日付を2未満にグループ化しています。もちろん、大量のデータを送信しているので、これらの各グループを、デザイン内の別々のビューに分割できます。ドキュメント、またはドキュメントの__id_のみを値(emit([ ...], doc._id);)として返します。

「couchdb」タグ(昇順)で「楽しい」カテゴリのすべてを取得します。

_?startkey=["fun", "couchdb"]&endkey=["fun", "couchdb", {}, {}]
_

「楽しい」カテゴリのすべてを「couchdb」タグ(降順)で取得します。

_?startkey=["fun", "couchdb", {}, {}]&endkey=["fun", "couchdb"]&descending=true
_

Couchdbタグ(昇順)で楽しいカテゴリのランキングのみを取得します。

_?startkey=["fun", "couchdb", 0]&endkey=["fun", "couchdb", 0, {}]_

「couchdb」タグ(降順)で「楽しい」カテゴリのランキングのみを取得します。

_?startkey=["fun", "couchdb", 0, {}]&endkey=["fun", "couchdb", 0]&descending=true
_

これがお役に立てば幸いです。複雑なキーは、データのスライスとダイシングにおけるMap/Reduceの威力を実際に示し始めます。

乾杯。

48
Sam Bisbee