web-dev-qa-db-ja.com

Mongodbの最後のNレコードを取得する方法?

これが文書化されているところはどこにもありません。デフォルトでは、find()操作は最初からレコードを取得します。 mongodbの最後のNレコードを取得するにはどうすればいいですか?

編集:また、私は返された結果が最新ではなく、新しいものから新しいものへと順序付けされて欲しいと思っています。

437
Bin Chen

私があなたの質問を理解したら、あなたは昇順にソートする必要があります。

"x"という名前のidフィールドまたはdateフィールドがあるとします。

。ソート()


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

1 は昇順にソートし(最も古いものから新しいものへ)、 -1 は降順にソートします(最も新しいものから最も古いものへ)。

自動作成された _id フィールドを使用する場合は日付が埋め込まれています。

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

それはあなたのすべての文書を古いものから新しいものへとソートして戻します。

ナチュラルオーダー


上記の Natural Order も使えます。

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);
621
Justin Jenkins

最新の _ n _ 追加されたレコードは、最新のものから最新のものまで、このクエリで見ることができます。

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

逆の順序でそれらが欲しいならば:

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

Mongo-Hacker をインストールすると/も使えます。

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

いつもこれらのコマンドを書くのに飽きたら、〜/ .mongorc.jsでカスタム関数を作成することができます。例えば。

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

それからmongoシェルからlast(N)とタイプしてください。

99

最後のNレコードを取得するには、以下のクエリを実行します。

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

最後のレコードが1つだけ必要な場合:

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

注:$ naturalの代わりに、コレクションから列の1つを使用できます。

13
Ashwini

sort()limit()skip()を使用して、スキップした値から最後のNレコードの先頭を取得できます。

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

クエリ:ソートと自然順、 http://www.mongodb.org/display/DOCS/Sorting+and+Natural+Order 、およびカーソルメソッドの下のsort()を参照してください。 http:// www .mongodb.org/display/DOCS /高度な+クエリ

5
Steve Wilhelm

コレクションのサイズに基づいて「スキップ」することはできません。クエリ条件が考慮されないためです。

正しい解決策は、目的のエンドポイントからソートし、結果セットのサイズを制限してから、必要に応じて結果の順序を調整することです。

これが実世界のコードに基づいた例です。

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
        });
    }
});
5
Marty Hirsch

あなたはこの方法を試すことができます:

コレクション内の総レコード数を取得する

db.dbcollection.count() 

それからskipを使ってください。

db.dbcollection.find().skip(db.dbcollection.count() - 1).pretty()
4
bello hargbola

@ bin-chen、

コレクション内の文書のサブセットの最新のn個のエントリーに集約を使用できます。これは、グループ化しない単純化した例です(この場合は、ステージ4と5の間で行います)。

これは最新の20個のエントリ( "timestamp"というフィールドに基づく)を昇順に並べ替えて返します。次に、各文書_id、タイムスタンプ、および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
}

お役に立てれば。

2
lauri108

ソート、スキップなどは、コレクションのサイズによってはかなり遅くなる可能性があります。

いくつかの基準でコレクションにインデックスを付けておくと、パフォーマンスが向上します。そして、あなたはmin()カーソルを使うことができます:

まず、db.collectionName.setIndex( yourIndex )を使ってコレクションにインデックスを付けます。昇順または降順を使用できます。これは、常に "最後のN個のアイテム"が必要なためです。 ".

次に、コレクションの最初の項目を見つけ、そのインデックスフィールド値を検索の最小基準として使用します。

db.collectionName.find().min(minCriteria).hint(yourIndex).limit(N)

これがmin()カーソルのリファレンスです。 https://docs.mongodb.com/manual/reference/method/cursor.min/

2
João Otero

findオプションを使用したいと思うかもしれません: http://docs.meteor.com/api/collections.html#Mongo-Collection-find

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

配列要素を制限するには $ slice 演算子を使用します

GeoLocation.find({},{name: 1, geolocation:{$slice: -5}})
    .then((result) => {
      res.json(result);
    })
    .catch((err) => {
      res.status(500).json({ success: false, msg: `Something went wrong. ${err}` });
});

ジオロケーションはデータの配列で、これから最後の5レコードを取得します。

0
KARTHIKEYAN.A
db.collection.find().hint( { $natural : -1 } ).sort(field: 1/-1).limit(n)

mongoDB Documentation :によると

クエリにフォワードコレクションスキャンを強制的に実行させるには、{$ natural:1}を指定できます。

{$ natural:-1}を指定して、クエリに強制的に逆コレクションスキャンを実行させることもできます。

0
Gili.il