我可以利用一些帮助从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的)观点,认为只有吐出来的是最新的日志给定设备。
这是我做的。这是临界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
看到最新的日志。
最后,“停止战斗”的东西是可选的。你可以简单地总是返回与最新的时间戳的文件。不过,我更愿意把它那里,因为在类似情况下,我想看看我是否映射,减少错误和空减产是我的大线索。