Obtenha o registro mais recente da coleção mongodb

99

Quero saber o registro mais recente de uma coleção. Como fazer isso?

Observação: eu sei que as seguintes consultas de linha de comando funcionam:

1. db.test.find().sort({"idate":-1}).limit(1).forEach(printjson);
2. db.test.find().skip(db.test.count()-1).forEach(printjson)

onde idate tem o carimbo de data / hora adicionado.

O problema é que a coleta é mais longa, é o tempo para recuperar os dados e minha coleta de 'teste' é realmente muito grande. Preciso de uma consulta com resposta em tempo constante.

Se houver alguma consulta de linha de comando mongodb melhor, me avise.

Inkriti
fonte

Respostas:

138

Esta é uma repetição da resposta anterior, mas é mais provável que funcione em diferentes versões do mongodb.

db.collection.find().limit(1).sort({$natural:-1})
Dígitos
fonte
10
db.collection.find().limit(1).sort({$natural:-1}).pretty()se você quiser que fique bonito
Anthony
Então, qual é a diferença com este pedido:db.collection.find().sort({$natural:-1}).limit(1).pretty()
Leão
@Digits qual será o impacto no desempenho se colocarmos um limite no final e também como o último registro é obtido quando você está limitando a saída a apenas um documento e deve ser o documento principal da coleção.
kailash yogeshwar
Boa resposta. Tentei assim: db.collection ("nome da coleção"). Find ({}, {limit: 1}). Sort ({$ natural: -1})
Abdul Alim Shakir
Para qualquer um usando AWS DocDB: Query failed with error code 303 and error message 'option $natural is not supported' on server docdb. Esperançosamente, esse recurso será lançado em breve.
Marc
34

Isso lhe dará um último documento para um collection

db.collectionName.findOne({}, {sort:{$natural:-1}})

$natural:-1 significa ordem oposta àquela em que os registros são inseridos.

Edit : Para todos os downvoters, acima é uma sintaxe Mongoose, a sintaxe mongo CLI é:db.collectionName.find({}).sort({$natural:-1}).limit(1)

dark_ruby
fonte
7
Sua sintaxe parece estar errada. Não consigo fazer com que funcione como você fez. O que funciona é: 'db.punchdeck.findOne ({$ query: {}, $ orderby: {$ natural: -1}})'
Dave Lowerre
não tenho certeza, por que todos os votos negativos - este código funciona perfeitamente para mim e é rápido
dark_ruby
2
@dark_ruby Sua consulta retorna o erro "$ err": "Não é possível canonizar a consulta: BadValue Opção de projeção não suportada: classificar: {$ natural: -1.0}",
Roman Podlinov
20

Eu preciso de uma consulta com resposta em tempo constante

Por padrão, os índices no MongoDB são árvores B. Pesquisar uma B-Tree é uma operação O (logN), então nem mesmo find({_id:...})fornecerá tempo constante, respostas O (1).

Dito isso, você também pode classificar por _idse estiver usando ObjectIdpara seus IDs. Veja aqui os detalhes . Claro, mesmo isso só é bom até o último segundo.

Você pode recorrer a "escrever duas vezes". Escreva uma vez para a coleção principal e escreva novamente para uma coleção "atualizada pela última vez". Sem transações isso não será perfeito, mas com apenas um item na coleção "última atualização" sempre será rápido.

Gates VP
fonte
2
Vejo muitas soluções noSQL e MongoDB defendendo "escrever duas vezes", principalmente para contadores quando o tamanho dos dados se torna muito grande. Estou supondo que esta é uma prática comum?
Vinny
O MongoDB não é liberado para o disco com muita frequência e não possui transações, portanto, as gravações se tornam significativamente mais rápidas. A compensação aqui é que você é encorajado a desnormalizar os dados, o que geralmente leva a várias gravações. Obviamente, se você obtiver taxa de transferência de gravação de 10x ou 100x (o que eu vi), 2x ou 3x as gravações ainda é uma grande melhoria.
Gates VP
13

Mais uma maneira de obter o último item de uma coleção MongoDB (não se preocupe com os exemplos):

> db.collection.find().sort({'_id':-1}).limit(1)

Projeção Normal

> db.Sports.find()
{ "_id" : ObjectId("5bfb5f82dea65504b456ab12"), "Type" : "NFL", "Head" : "Patriots Won SuperBowl 2017", "Body" : "Again, the Pats won the Super Bowl." }
{ "_id" : ObjectId("5bfb6011dea65504b456ab13"), "Type" : "World Cup 2018", "Head" : "Brazil Qualified for Round of 16", "Body" : "The Brazilians are happy today, due to the qualification of the Brazilian Team for the Round of 16 for the World Cup 2018." }
{ "_id" : ObjectId("5bfb60b1dea65504b456ab14"), "Type" : "F1", "Head" : "Ferrari Lost Championship", "Body" : "By two positions, Ferrari loses the F1 Championship, leaving the Italians in tears." }

Projeção classificada (_id: ordem inversa)

> db.Sports.find().sort({'_id':-1})
{ "_id" : ObjectId("5bfb60b1dea65504b456ab14"), "Type" : "F1", "Head" : "Ferrari Lost Championship", "Body" : "By two positions, Ferrari loses the F1 Championship, leaving the Italians in tears." }
{ "_id" : ObjectId("5bfb6011dea65504b456ab13"), "Type" : "World Cup 2018", "Head" : "Brazil Qualified for Round of 16", "Body" : "The Brazilians are happy today, due to the qualification of the Brazilian Team for the Round of 16 for the World Cup 2018." }
{ "_id" : ObjectId("5bfb5f82dea65504b456ab12"), "Type" : "NFL", "Head" : "Patriots Won SuperBowl 2018", "Body" : "Again, the Pats won the Super Bowl" }

sort({'_id':-1}), define uma projeção em ordem decrescente de todos os documentos, com base em seus _ids.

Projeção classificada (_id: ordem inversa): obtendo o documento mais recente (último) de uma coleção.

> db.Sports.find().sort({'_id':-1}).limit(1)
{ "_id" : ObjectId("5bfb60b1dea65504b456ab14"), "Type" : "F1", "Head" : "Ferrari Lost Championship", "Body" : "By two positions, Ferrari loses the F1 Championship, leaving the Italians in tears." }
Ivanleoncz
fonte
2

php7.1 mongoDB:
$data = $collection->findOne([],['sort' => ['_id' => -1],'projection' => ['_id' => 1]]);

Sam
fonte
1

Minha solução:

db.collection("name of collection").find({}, {limit: 1}).sort({$natural: -1})

Abdul Alim Shakir
fonte
0

Se você estiver usando Ids de objeto Mongo gerados automaticamente em seu documento, ele contém o carimbo de data / hora como os primeiros 4 bytes, usando o documento mais recente inserido na coleção que pôde ser encontrado. Eu entendo que essa é uma pergunta antiga, mas se alguém ainda está acabando aqui procurando mais uma alternativa.

db.collectionName.aggregate(
[{$group: {_id: null, latestDocId: { $max: "$_id"}}}, {$project: {_id: 0, latestDocId: 1}}])

A consulta acima forneceria o _id para o documento mais recente inserido na coleção

Chan15
fonte
0

Veja como obter o último registro de todos os documentos MongoDB da coleção "foo". (Altere foo, x, y .. etc.)

db.foo.aggregate([{$sort:{ x : 1, date : 1 } },{$group: { _id: "$x" ,y: {$last:"$y"},yz: {$last:"$yz"},date: { $last : "$date" }}} ],{   allowDiskUse:true  })

você pode adicionar ou remover do grupo

artigos de ajuda: https://docs.mongodb.com/manual/reference/operator/aggregation/group/#pipe._S_group

https://docs.mongodb.com/manual/reference/operator/aggregation/last/

ssymbiotik
fonte