mongodb: как получить последние N записей?

Я не могу найти нигде документально это. По умолчанию операция find () будет получать записи с самого начала. Как я могу получить последние N записей в mongodb?

Edit: также я хочу, чтобы возвращаемый результат был упорядочен от менее недавнего до самого последнего, а не наоборот.

9 ответов


если я понимаю ваш вопрос, вам нужно сортировать в порядке возрастания.

предполагая, что у вас есть какой-то идентификатор или поле даты под названием "x", вы бы сделали ...

.sort ()


db.foo.find().sort({x:1});

на 1 будет сортировать по возрастанию (от старейшего до новейшего) и -1 сортирует по убыванию (от новейшего до старейшего.)

если вы используете auto created параметр _id поле имеет встроенную в него дату ... так что вы можете использовать это, чтобы заказать ...

db.foo.find().sort({_id:1});

это вернет все ваши документы, отсортированные от старейших до новейших.

Естественный Порядок


вы также можете использовать Естественный Порядок упоминалось выше ...

db.foo.find().sort({$natural:1});

опять же, с помощью 1 или -1 в зависимости от того, что вы хотите.

использовать .limit ()


наконец, рекомендуется добавить ограничение при выполнении такого рода широко открытого запроса, чтобы вы мог сделать и то, и другое ...

db.foo.find().sort({_id:1}).limit(50);

или

db.foo.find().sort({$natural:1}).limit(50);

последние N добавленные записи, от менее недавних до самых последних, можно увидеть с помощью этого запроса:

db.collection.find().skip(db.collection.count() - N)

если вы хотите их в обратном порядке:

db.collection.find().sort({ $natural: -1 }).limit(N)

при установке Монго-Хакер вы также можете использовать:

db.collection.find().reverse().limit(N)

если вы устали писать эти команды все время, вы можете создавать пользовательские функции в своем ~/.mongorc.js. Е. Г.

function last(N) {
    return db.collection.find().skip(db.collection.count() - N);
}

тогда из оболочки mongo просто введите last(N)


чтобы получить последние N записей, вы можете выполнить следующий запрос:

db.yourcollectionname.find({$query: {}, $orderby: {$natural : -1}}).limit(yournumber)

Если вы хотите только одну последнюю запись:

db.yourcollectionname.findOne({$query: {}, $orderby: {$natural : -1}})

Примечание: вместо $natural вы можете использовать один из столбцов из своей коллекции.


можно использовать sort() , limit() ,skip() чтобы получить последние N записей из пропущенных значение

db.collections.find().sort(key:value).limit(int value).skip(some int value);

вы не можете" пропустить " на основе размера коллекции, потому что он не будет учитывать условия запроса.

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

вот пример, основанный на реальном коде.

var query = collection.find( { conditions } ).sort({$natural : -1}).limit(N);

query.exec(function(err, results) {
    if (err) { 
    }
    else if (results.length == 0) {
    }
    else {
        results.reverse(); // put the results into the desired order
        results.forEach(function(result) {
            // do something with each result
        });
    }
});

посмотрите под запросом: сортировка и естественный порядок,http://www.mongodb.org/display/DOCS/Sorting + и + естественный + порядок а также sort () под методами Курсора http://www.mongodb.org/display/DOCS/Advanced + запросы


вы можете использовать find параметры : http://docs.meteor.com/api/collections.html#Mongo-Collection-find

db.collection.find({}, {sort: {createdAt: -1}, skip:2, limit: 18}).fetch();

@bin-chen,

можно использовать агрегацию для последних n записей подмножества документов в коллекции. Вот упрощенный пример без группировки (что вы будете делать между этапами 4 и 5 в этом случае).

Это возвращает последние 20 записей (в поле "метки"), отсортированный по возрастанию. Затем он проецирует каждый documents _id, timestamp и whatever_field_you_want_to_show в результаты.

var pipeline = [
        {
            "$match": { //stage 1: filter out a subset
                "first_field": "needs to have this value",
                "second_field": "needs to be this"
            }
        },
        {
            "$sort": { //stage 2: sort the remainder last-first
                "timestamp": -1
            }
        },
        {
            "$limit": 20 //stage 3: keep only 20 of the descending order subset
        },
        {
            "$sort": {
                "rt": 1 //stage 4: sort back to ascending order
            }
        },
        {
            "$project": { //stage 5: add any fields you want to show in your results
                "_id": 1,
                "timestamp" : 1,
                "whatever_field_you_want_to_show": 1
            }
        }
    ]

yourcollection.aggregate(pipeline, function resultCallBack(err, result) {
  // account for (err)
  // do something with (result)
}

Итак, результат будет выглядеть примерно так:

{ 
    "_id" : ObjectId("5ac5b878a1deg18asdafb060"),
    "timestamp" : "2018-04-05T05:47:37.045Z",
    "whatever_field_you_want_to_show" : -3.46000003814697
}
{ 
    "_id" : ObjectId("5ac5b878a1de1adsweafb05f"),
    "timestamp" : "2018-04-05T05:47:38.187Z",
    "whatever_field_you_want_to_show" : -4.13000011444092
}

надеюсь, что это помогает.


последняя функция должна быть sort, а не limit.

пример:

db.testcollection.find().limit(3).sort({timestamp:-1});