0

私はしばらくの間、これを理解しようとしてきました.SOの質問をたくさん読んだり、ドキュメントを調べたりしましたが、役に立ちませんでした. ここの誰かが私を正しい方向に向けてくれることを願っています!

次のドキュメントを検討してください。

{
    "_id": "045bdeb40176b33cf07b21cd1fb3949e",
    "type": "test_result",
    "customer_id": "customer",
    "product_id": "product1",
    "type_id": "type",
    "version_id": "1.0.0",                      

    "timestamp": 1381505909000,
    "test_result": "passed",

    "serial_nr": "NEP000001"
}

{
    "_id": "045bdeb40176b33cf07b21cd1fb3c434",
    "type": "measurement_result",
    "test_result_id": "045bdeb40176b33cf07b21cd1fb3949e",

    "measurement_id": "customer:product1:type:1.0.0:0",
    "timestamp": 1381505909000,
    "data": 2.5                                 
}

アプリケーションには、さまざまな方法で測定された単位のデータが含まれています。test_resultユニットがテストされるたびに、1 つのドキュメントが挿入されます。各ユニットには固有のserial_nr. ユニットで行われる測定ごとに1 つのmeasurement_resultドキュメントが挿入されます (通常、ユニットごとに約 50 の測定)。その単位の各測定値には固有の がありmeasurement_idます。結果が挿入されると、timestampが生成されます。1 つのユニットを複数回テストできます。

私が構築しようとしているビューは次のとおりです。

  1. ユニットが初めてテストされたすべてのデータを取得します。
  2. ユニットがテストされた最新の時間のすべてのデータを取得します。
  3. 1 つの のすべての測定値を取得しますmeasurement_idが、最も古い結果のみを取得します。1 つのユニットが複数回テストされている場合は、最初のテストの測定結果のみを含める必要があります。
  4. 1 つの のすべての測定値を取得しますmeasurement_idが、最新の結果のみを取得します (最も古い結果と同じルール)。

目標は、 、、などのdata統計を計算するフィールドを減らすことです。ユニットがテストされた最初/最新の時間で統計を分離できることは非常に重要です。averageminmaxstandard deviation

複雑なキー、非常に高度な削減、および他の多くのアプローチを使用しようとしましたが、最新/最新の結果を分離できないようです。

このアプリケーションはまだ実稼働にはほど遠いので、どんな解決策も歓迎します (データベース システムを切り替えることもあると思います)。他の方法でデータを構造化する必要がありますか? これは可能ですか?長期的には大量のデータが得られるため、統計を段階的に計算できることが非常に重要です。

この質問は私のものと多かれ少なかれ同じようですが、答えはありませんでした。

更新 #1

ケース #1 と #2 の場合は、おそらく単にマップし[serial_nr, timestamp]てから reduce_limit をオフにして、最新のエントリのみを返すことができるようにすることができます。それが長期的にパフォーマンスにどのように影響するかわかりませんか?

#3 と #4 の場合、それはより困難です。grouped by を計算するmeasurement_id必要があるため、キー配列の最初の要素である必要があります。しかし、その後は?

(簡単にするために、measurement_resultドキュメントにも があると仮定しますserial_nr)

map: 
    function(doc) {
        if (doc.type == 'measurement_result')
            emit([doc.measurement_id, doc.serial_nr, doc.timestamp], doc.data)
    }

reduce: 
    _stats

GETここではwithgroup_level=1が唯一のオプションです。そうしないと、各 Measurement_id に対して個別の結果が得られるためです。ただし、最新または最も古い結果のみを除外することはまだできていません。おそらく、reduce 関数を作成して重複serial_nrをチェックし、最新/最も古いものだけを返すことができますが、その方法がわかりません。

これで問題が少し解決することを願っています。

4

1 に答える 1

3

あなたが犯しているかもしれない間違いの 1 つは、RDBMS の方法でデータを整理しようとしていると思います。正直なところ、測定値が約 50 程度しかない場合は、同じドキュメントに簡単に含めることができます。エントリの量に上限がない場合にのみ心配する必要があります....同じドキュメントに何千ものエントリがありましたが、お勧めしません。

配列に値を順番に追加できる関数を作成するだけで、 couchdb の更新ハンドラを使用できます。ここにクイック リファレンスがあります。

基本的に、更新ハンドラーはドキュメントが存在しない場合は作成し、配列にエントリを追加する必要があります。あなたの例を使用すると、 -measurements と -test-result を簡単な自然キーとして持つことができます。新しいドキュメントは次のようになります。

{
    "_id": "NEP000001-measurements",
    "type": "measurement_result",
    "test_result_id": "045bdeb40176b33cf07b21cd1fb3949e",
    "serial_nr": "NEP000001",
    "measurements": [
        {
            "measurement_id": "customer:product1:type:1.0.0:0",
            "timestamp": 1381505909000,
            "test_result_id": "045bdeb40176b33cf07b21cd1fb3949e",
            "data": 2.5
        },
        {
            "measurement_id": "customer1:product2:type:1.0.0:0",
            "timestamp": 1381505909005,
            "test_result_id": "045bdeb40176b33cf07b21cd1fb3949e",
            "data": 2.7
        }
    ]
}

Couchdb ビューを使用すると、最終的にビューに表示されるものと、データベース内のデータがどのように見えるかを分割できます。

とにかく、この後、次のようなビュー関数を持つことができます: 1) first _view/first_measurements

map: function(doc) { if (doc.type == 'measurement_result'){ var first = doc.measurements[0]; emit([first.measurement_id, doc.serial_nr, first.timestamp], first.data) } }

reduce: _stats

2) _view/latest マップ: function(doc) { if (doc.type == 'measurement_result'){ var last = doc.measurements[doc.measurements.length-1]; emit([last.measurement_id, doc.serial_nr, last.timestamp], last.data) } }

reduce: _stats

//measurement_id とドキュメントの id の違いと一意である必要があるものについて少し混乱しているので、まだ答えられないかもしれませんが、startkey と endkey の範囲を降順と組み合わせて使用​​できるようです= false ...必要なものを取得するには..また、 include_doc=true は、値を発行したドキュメントを取得するためにここで役立つかもしれません....(またはデータベース内の他のドキュメント:-))..とにかくこれを願っています役立ちます

于 2013-10-17T19:18:20.177 に答える