Какой метод идеально подходит для запроса 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 дней", но вместо этого используются номера недель.

Другие вопросы по тегам