Какой метод идеально подходит для запроса Cloudant для последнего документа, имеющего то же значение для поля, и снова фильтрации по этому результату?
Я очень новичок в NoSQL. Мой сценарий использования связан с этим.... Многие пользователи публикуют сообщения, и мы храним их в облаке как разные документы.
{
id:random,
userid:xxx,
timestamp: 1449216912282,
msg: "Hi..."
}
Я хочу узнать пользователей, которые ничего не публиковали в течение последних 5 дней. Кроме того, я хочу знать, публиковали ли они что-либо в течение последних 5-10 дней. Если они есть, то отправьте письмо с напоминанием пользователю, чтобы быть активным.
Какой вариант будет лучше - просмотры, поиск, облачный запрос? Предположим, у нас будет 1000 сообщений в час
Хотя при создании view - map(userid,timestamp) уменьшаем как _stats и получаем максимальную метку времени каждого пользователя. Затем повторяем этот список - мы получаем пользователей, которые не публиковали сообщения в течение последних 5 дней. Другим вариантом было использование поискового индекса, получение всех идентификаторов пользователей между необходимыми временными метками. Сравните оба списка в приложении.
Есть ли способ сделать это в одном запросе, не перегружая приложение? Поможет ли изменение формата данных или создание соответствующего индекса или просмотра?
1 ответ
Если ваши данные выглядели так:
{
"_id": "abcdefghijklmon1234",
"userid" : "user1",
"timestamp": 1449739485035,
"msg": "Hi"
}
Вы можете создать представление MapReduce, которое создало индекс с ключом, состоящим из [ 2015, 50, "user1" ]
где "2015" - это год, "50" - номер недели, а "user1" - идентификатор пользователя документа. Это может быть достигнуто с помощью функции Map:
function (doc) {
var getWeek = function(t) {
var date = new Date(t);
date.setHours(0, 0, 0, 0);
date.setDate(date.getDate() + 3 - (date.getDay() + 6) % 7);
var week1 = new Date(date.getFullYear(), 0, 4);
return 1 + Math.round(((date.getTime() - week1.getTime()) / 86400000 - 3 + (week1.getDay() + 6) % 7) / 7);
};
if (typeof doc.timestamp == "number") {
var d = new Date(doc.timestamp);
var weeknum = getWeek(d.getTime());
var year = d.getFullYear();
emit( [ year, weeknum, doc.userid], null);
}
}
с уменьшением "_count". Это позволяет такие запросы, как ?startkey=[2015,49]&endkey=[2015,50]&group_level=3
чтобы получить список пользователей, которые постили на прошлой неделе. Список пользователей, которые не являются пользователями, которых нет в приведенном выше списке.
Это не решение вашей проблемы с точки зрения "за последние 5 дней", но вместо этого используются номера недель.