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每次测试一个单元时插入一个文档。每个单元都有一个独特的serial_nr. 对一个单元进行的每次测量都会插入一个measurement_result文档(通常每个单元大约 50 次测量)。该单位的每个测量值都有一个唯一的measurement_id. 插入结果后,将timestamp生成 。一个单元可以进行多次测试。

我正在尝试构建的视图如下:

  1. 检索第一次测试单元的所有数据。
  2. 检索最近一次测试单元的所有数据。
  3. 检索 one 的所有测量值measurement_id,但仅限于最旧的结果。如果任何一个单元已被多次测试,则仅应包括第一次测试的测量结果。
  4. 检索 one 的所有测量值measurement_id,但仅限于最近的结果(与最旧结果的规则相同)。

目标是减少data计算统计数据的字段,如average, min,maxstandard deviation并且能够按单元测试的第一次/最后一次分离统计数据是非常有价值的。

我一直在尝试使用复杂的键、非常高级的减少和许多其他方法,但我似乎无法隔离最新/最新的结果。

该应用程序仍远未生产,因此欢迎任何解决方案(我猜甚至切换数据库系统)。我应该以任何其他方式构造数据吗?这甚至可能吗?从长远来看,我将拥有大量数据,因此可以增量计算统计数据非常重要。

这个问题似乎和我的差不多,但从来没有任何答案,我已经和他一样了。

更新#1

对于 #1 和 #2 的情况,我可能只映射[serial_nr, timestamp]然后关闭 reduce_limit 以允许我只返回最近的条目。我不知道从长远来看这会如何影响性能?

对于#3 和#4,它更难。由于我需要计算分组,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

GETwithgroup_level=1是我在这里唯一的选择,因为否则我将获得每个measurement_id 的单独结果 - 但我仍然没有设法仅过滤掉最新或最旧的结果,这只会让我得到所有结果。现在我也许可以编写一个 reduce 函数来以某种方式检查重复项serial_nr并只返回最新/最旧的,但我不知道如何。

希望这能稍微澄清一下这个问题。

4

1 回答 1

3

我认为您可能犯的一个错误是尝试以 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

地图:函数(文档){如果(doc.type =='measurement_result'){var first = doc.measurements[0]; 发射([first.measurement_id,doc.serial_nr,first.timestamp],first.data)}}

减少:_stats

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

减少:_stats

//我对measurement_id和文档id之间的区别以及必须是唯一的东西有点困惑,所以我可能还不能回答这个问题,但听起来你可以使用startkey和endkey范围结合可能的降序= false...得到你想要的..include_doc=true 在这里可能会派上用场,用于检索发出值的文档....(或数据库中的任何其他文档:-))..无论如何希望这个帮助

于 2013-10-17T19:18:20.177 回答