2012-02-09 19 views
3

私はCouchDBについての理解を深め、実際のシナリオではデータをモデル化する方法を模索しています。日付は依頼することも可能であるエポックであるCouchDBモデリング - 時間フィルタリングとグループデータ

{ 
    "_id": "couch1", 
    "_rev": "2-338d0a592ad1e5570000002b00000000", 
    "eventType": "event1", 
    "date": 1328805860000 
} 

{ 
    "_id": "couch2", 
    "_rev": "1-1e0315c2e1ca7f5f0000002b00000000", 
    "eventType": "event1", 
    "date": 1328133600000 
} 

{ 
    "_id": "couch3", 
    "_rev": "1-154cd416b78cb2ef0000002b00000000", 
    "eventType": "event2", 
    "date": 1325434920000 
} 

:)そうのような

考える文書を、私は今のことができますように私は、「日付で私を得るブログの投稿」などの多くを行ってきましたあなたが2つのタイムスタンプの間に起こったすべての "イベント"を尋ねたところで、そのデータを "eventType"でグループ化するためにソファを作るのですか?

"event1": 2 
"event2": 1 

私はそれを意識してい

を取得したさらなる情報を:私たちは、出力を見てみたいと思います - だから、上記と包含するでそれらの文書を渡されたタイムスタンプを仮定を使用して

ソファはキーでソートされるので、もし私が「トップ10」を望むなら、それは第二段階になるだろうが、私はそれを扱うことができる。

ここで重要な問題は、1つの列でフィルタリングしてから別の列でグループ化することです。

我々は、次のマップ機能を使用する場合:私たちはタイムスタンプが本質的であるため、ユニークなソファーがグループとキーをすることができますので、値1

を持っていることができないことがわかり機能を減らすcount

function (doc) { 
    emit([doc.date, doc.eventType], doc.eventType); 
} 

を以下に、マップ機能を変更します。その後、

function (doc) { 
    emit([doc.eventType, doc.date], doc.eventType); 
} 

とイベントBUによって正しくgroup level 1にその意志グループを変更あなたのプライマリ注文はイベント名によるものなので、あなたのデータを時間でスライスすることはできません。つまり、時間の順序が壊れていますか?

これに関する戦争物語はありますか?これは再削減する必要がありますか?この

Eggsy

+0

答えは素晴らしいです。キー** A **での選択/選択とキー** B **によるグループ化は、基本的に2次元のクエリであることに注意してください。 CouchDBのビューは常に* 1次元です。 – JasonSmith

+0

だから、本質的には最も効率的なやり方で行えず、DBに動かすことはできないと言っています。私たちは常にクライアント上でグループ化を行うことができますが、私たちはむしろそうしないでしょう。この種の問題は、分析の問題の典型的な形であり、大規模なデータ用に構築された他のNoSQLソリューションがそのようなタスクを実行できるかどうか疑問に思う。 – eggsy84

答えて

0

を読むために時間を割いて誰にも事前に

多くのおかげで、あなたは、イベントタイプの固定数を持っていますか?それは比較的小さく静的なリストですか?

そうでない場合は、残りの回答をスキップしてください。

もしそうなら、迅速かつ汚れたオプションをお読みください。

map.js関数を変更して、イベントタイプの値に基づいて複数のemit()関数を設定できます。

if(eventType == event1) {emit(doc.date, {'eventType1': 1} 

イベントタイプごとに繰り返します。

emit(doc.date, doc). 

その後、あなたが持っている:あなたは値として1を持つフィールドとしてなどeventType1、eventType2を、持っているあなたの文書を変更することができるかどうか...その後ナンセンスだけが場合は、あなたはすべての空想をスキップすることができます減らす。行によるJS機能ループ、最終的に次のようになりますオブジェクトに追加します:

{eventType1:25、eventType2:2、...}のグループまたはグループなしで閲覧

for (i = 0; i < values.length; i++){ 
    if (values[i].eventType1 > 0) { eventType1 += 1 } 
    if (values[i].eventType2 > 0) { eventType2 += 1 } 
    ... 
} 

クエリを= falseそしてあなたのイベントタイプとそのカウントでヌルキーを持つ単一レコードを取得する必要があります。

私はこれと同様のタイプのリクエストを処理しています。しかし、私の "eventType"リストは決して変更されません。

+0

残念ながら。しかし、アイデアをありがとう。起こった出来事は、決して事前に知ることができず、大きなサイズに成長する可能性があります。 – eggsy84

+0

あなたの最善の策は、List関数を使うことです。あなたのeventTypeリストが本当に大きくなったら、連鎖可能なmap/reduceを探してください。 – user791770

1

私はビュー/リストのコンボを示唆している:

ビュー:

"eventByDate": 
{ 
    "map": "function(doc) { emit(doc.date, doc.eventType);}" 
} 

一覧:

"test": "function(head,req) { 
    var eventO=new Object(); 
    while(row=getRow()) { 
    if(eventO[row.value]==undefined) { 
    eventO[row.value]=1; 
    }else{ 
    eventO[row.value]++; 
    } 
} 
send("["); 
for (var curEvent in eventO) { 
    send ("{\"event\":\""+curEvent +"\",\"count\":"+eventO[curEvent]+"}"); 
} 
send("]"); 
}" 

結果:

[ 
{"event":"event2","count":1} 
{"event":"event1","count":2} 
] 

しかし、あなたはで注文する必要があり手動でカウントする(私は実装しなかったここでまたはあなたのバックエンドで

+0

こんにちは、オリバー。スタックオーバーフローであなたを見ていいです! – JasonSmith

0

@ user791770のようにすることができますが、コードをわずかに変更してイベントタイプのリストをハードコードする必要はありません。

地図:

function(doc) { 
    var data = {}; 
    data[doc.type] = 1; 
    emit(doc.time, data); 
} 

は削減:

function(keys, values, rereduce) { 
    var data = {}; 
    for (i = 0; i < values.length; i++) { 
    for (var field in values[i]) { 
     if (typeof data[field] == 'undefined') data[field] = 0; 
     data[field] += values[i][field]; 
    } 
    } 
    return data; 
} 
関連する問題