Вот что я делаю.Это пограничное злоупотребление CouchDB, однако я добился большого успеха.
Обычно reduce
вычисляет сумму, или число, или что-то в этом роде.Тем не менее, думать о снижении как отборочном турниреМногие ценности входят. Только одно выходит.Сокращение!Повторяйте снова и снова, и вы получите окончательного победителя (повторное сокращение).В этом случае победителем становится журнал с последней отметкой времени.
Конечно, полусредние не могут бороться с тяжеловесами.Должны быть лиги и весовые категории.Имеет смысл только для определенных документов сражаться с некоторыми другими подобными документами.Это именно то, что будет делать параметр Reduce group .Это обеспечит попадание в стальную клетку нашего кровавого спортсмена только одинаково подобранного гладиатора.(Кофе начинает работать.)
Сначала выведите все журналы, набранные устройством.Выдаваемый 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
.
Наконец, «остановить бой» не является обязательным. Вы всегда можете просто вернуть документ с последней отметкой времени. Однако я предпочитаю сохранять его там, потому что в подобных ситуациях я хочу посмотреть, являюсь ли я картой- неправильное уменьшение, и нулевой вывод - моя большая подсказка.