CouchDB的 - 从列表过滤每记录例如最新的日志

问题描述 投票:3回答:1

我可以利用一些帮助从CouchDB的视图过滤不同的值。我有一个日志存储有关计算机信息的数据库。定期对计算机新日志写入到数据库。

有点简化的I存储如下条目:

{
   "name": "NAS",
   "os": "Linux",
   "timestamp": "2011-03-03T16:26:39Z",
}
{
   "name": "Server1",
   "os": "Windows",
   "timestamp": "2011-02-03T19:31:31Z",
}
{
   "name": "NAS",
   "os": "Linux",
   "timestamp": "2011-02-03T18:21:29Z",
}

到目前为止,我奋力过滤该列表由不同的条目。我想收到的每个设备的最新日志文件。

我有这样一个观点:

function(doc) {
    emit([doc.timestamp,doc.name], doc);
}

进出口查询这一观点与Python(couchdbkit)和最佳的解决方案,我想出了到目前为止是这样的:

def get_latest_logs(cls):
    unique = []
    for log in cls.view("logs/timestamp", descending=True):
        if log.name not in unique_names:
            unique.append(log)
    return unique

好吧......这工作。但是,我有强烈的感觉,那是蟒蛇需要迭代的日志文件的完整列表(这有可能成为相当长的),这是不是最好的解决方案。

我想我需要一个减少功能,但我真的不能找到,我可以适应我的问题的任何实例或解释。

所以,我在找的是一个(纯CouchDB的)观点,认为只有吐出来的是最新的日志给定设备。

python couchdb mapreduce couchdbkit
1个回答
6
投票

这是我做的。这是临界CouchDB的虐待,但是我有很大的成功。

通常情况下,reduce将计算总和,或计数,或者类似的东西。然而,认为减少作为淘汰赛的。许多价值观去。只有一个出来。的减少!重复一遍又一遍,你有最终的赢家(再降低)。在这种情况下,日志与最新的时间戳是赢家。

当然,welterweights的不能打的重量级人物。有必须是联赛和质量等级。很有道理的某些文件做一些其它类似文件的战斗。这也正是降低组的参数就可以了。这将确保只有均匀匹配的角斗士在我们拳霸进入钢筋笼。 (咖啡被踢英寸)

首先,由发射设备键控所有日志。发出的value仅仅是该文件的一个副本。

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

接下来,编写一个减少函数返回所有给定值的最新时间戳。如果你看到来自不同联赛(两个日志来自不同系统)两大角斗士之间的争斗,停止战斗!出事了(有人质疑不正确group值)。

function(keys, vals, re) {
    var challenger, winner = null;
    for(var a = 0; a < vals.length; a++) {
        challenger = vals[a];
        if(!winner) {
            // The title is unchallenged. This value is the winner.
            winner = challenger;
        } else {
            // Fight!
            if(winner.name !== challenger.name) {
                // Stop the fight! He's gonna kill him!
                return null; // With a grouping query, this will never happen.
            } else if(winner.timestamp > challenger.timestamp) {
                // The champ wins! (Nothing to do.)
            } else {
                // The challenger wins!
                winner = challenger;
            }
        }
    }

    // Today's champion lives to fight another day.
    return winner;
}

(请注意,时间戳的比较可能是错误的。你将不得不转换为Date可能。)

现在,当你查询视图与?group=true,然后CouchDB的只会减少与同key,这是你的机器名(发现之间的胜者)值。

(您也可以发出一个数组作为重点,这给了更多的灵活性。你可以emit([doc.name, doc.timestamp], doc)来代替。这样你就可以通过系统与像?reduce=false&startkey=["NAS", null]&endkey=["NAS", {}]查询看到所有的日志,或者您可以通过系统?group_level=1看到最新的日志。

最后,“停止战斗”的东西是可选的。你可以简单地总是返回与最新的时间戳的文件。不过,我更愿意把它那里,因为在类似情况下,我想看看我是否映射,减少错误和空减产是我的大线索。

© www.soinside.com 2019 - 2024. All rights reserved.