Как поддерживать временной интервал при поиске документов из коллекции mongodb?

У меня есть документы ниже, сохраненные в коллекции mongodb. Они отсортированы по возрастанию. Я хочу получить только один документ за указанный промежуток времени. (Я использую node.js с драйвером node-mongodb.) Как мне его реализовать?

{"created_at":"2013-03-19T07:14:05Z"}
{"created_at":"2013-03-19T07:35:40Z"}
{"created_at":"2013-03-19T07:59:52Z"}
{"created_at":"2013-03-19T08:01:32Z"}
{"created_at":"2013-03-19T08:02:40Z"}
{"created_at":"2013-03-19T08:02:56Z"}
{"created_at":"2013-03-19T08:06:24Z"}
{"created_at":"2013-03-19T08:07:08Z"}
{"created_at":"2013-03-19T08:23:27Z"}
{"created_at":"2013-03-19T08:27:44Z"}
{"created_at":"2013-03-19T08:27:58Z"}
{"created_at":"2013-03-19T08:28:04Z"}
{"created_at":"2013-03-19T08:28:08Z"}
{"created_at":"2013-03-19T08:28:23Z"}

Например, если интервал времени составляет 1 минуту, ожидаемый результат будет таким, как показано ниже.

{"created_at":"2013-03-19T07:14:05Z"}
{"created_at":"2013-03-19T07:35:40Z"}
{"created_at":"2013-03-19T07:59:52Z"}
{"created_at":"2013-03-19T08:01:32Z"}
{"created_at":"2013-03-19T08:02:40Z"}
{"created_at":"2013-03-19T08:06:24Z"}
{"created_at":"2013-03-19T08:07:08Z"}
{"created_at":"2013-03-19T08:23:27Z"}
{"created_at":"2013-03-19T08:27:44Z"}
{"created_at":"2013-03-19T08:28:04Z"}

Приведенные ниже документы возврату не подлежат.

{"created_at":"2013-03-19T08:02:56Z"}
{"created_at":"2013-03-19T08:27:58Z"}
{"created_at":"2013-03-19T08:28:08Z"}
{"created_at":"2013-03-19T08:28:23Z"}

Спасибо,

Джеффри


person Jeffrey    schedule 19.03.2013    source источник
comment
Нет. Это разные вопросы.   -  person Jeffrey    schedule 19.03.2013
comment
Map / Reduce - это то, что вы ищете.   -  person freakish    schedule 19.03.2013
comment
@Freakish, можешь дать ссылку для подробностей?   -  person Jeffrey    schedule 19.03.2013
comment
Другой подход, который следует рассмотреть, - использовать структуру агрегации MongoDB: docs.mongodb.org/manual/applications/ агрегирование   -  person Hector Correa    schedule 19.03.2013


Ответы (1)


Map / Reduce - это то, что вы ищете.

Подумайте о своей коллекции так: у вас есть документы, в которых created_at становится идентификатором. Или я должен сказать, что часть created_at с точностью до минуты. Так, например, эта функция будет использоваться для определения идентификатора:

var GenerateID = function(date) {
    return date.getFullYear() + "/" +
           date.getMonth() + "/" +
           date.getDate() + "." +
           date.getHours() + ":" +
           date.getMinutes();
};

Таким образом, эта функция преобразует объект даты в строку, включающую год, месяц, день, час и минуту. Нас не интересуют секунды, потому что вам нужен только один объект в минуту.

Теперь вам нужно определить функции map и reduce. Например, карта может выглядеть так:

var map = function() {
    var key = GenerateID(this.created_at);
    emit(key, this);
};

и уменьшить:

var reduce = function(key, values) {
    if (values.length) {
        return values[0];
    }
};

Здесь мы просто возвращаем первое имеющееся значение (в сочетании с сортировкой даст вам то, что вы хотите). Обратите внимание, что это для каждого ключа, так что у нас все хорошо.

Теперь вам нужно уволить эту работу на стороне Монго. В зависимости от вашего драйвера это может выглядеть так:

db.collection.mapReduce(
    map,
    reduce,
    {
        out: { inline: 1 },
        query: // your range query
        sort: // by created_at
        scope: { GenerateID: GenerateID },
    }
)

Вот официальный обзор карты / сокращения MongoDB:

http://docs.mongodb.org/manual/applications/map-reduce/

person freakish    schedule 19.03.2013