web-dev-qa-db-ja.com

mongodbコレクションで最も古い/最も若い投稿を見つける

多くのフィールドを持つmongodbコレクションがあります。 1つのフィールドは「date_time」で、これはISO日時形式です。例:ISODate("2014-06-11T19:16:46Z")、もう1つのフィールドは「name」です。

nameが与えられた場合、コレクション内の最も古い/最も若い投稿を見つけるにはどうすればよいですか?

例:コレクション 'data'にtwoの投稿がある場合:

_[{'name' : 'John', 'date_time' : ISODate("2014-06-11T19:16:46Z")},
 {'name' : 'John', 'date_time' : ISODate("2015-06-11T19:16:46Z")}]
_

'John'という名前の場合、コレクション内の最も古い投稿、つまりISODate("2014-06-11T19:16:46Z")の投稿を見つけるにはどうすればよいですか?最年少のポストについても同様です。

16
user3799658

最も古い:

db.posts.find({ "name" : "John" }).sort({ "date_time" : 1 }).limit(1)

最新:

db.posts.find({ "name" : "John" }).sort({ "date_time" : -1 }).limit(1)

クエリを効率的にするために、{ "name" : 1, "date_time" : 1 }のインデックスを作成します。

26
wdberkeley

以下のように集計できます。

  • indexおよび_date_time_フィールドにnameを作成して、_$match_および_$sort_ステージ操作で使用できるようにします。

    db.t.ensureIndex({"name":1,"date_time":1})

  • _$match_目的のname(s)のすべてのレコード。

  • _$sort_ by _date_time_昇順。
  • _$group_ nameフィールド。 $ first 演算子を使用して、グループの最初のレコードを取得します。これも最も古いレコードになります。 $ last 演算子を使用して、グループ内の最後のレコードを取得します。これも最新です。
  • レコード全体を取得するには、 $$ ROOT システム変数を使用します。

コード:

_db.t.aggregate([
{$match:{"name":"John"}},
{$sort:{"date_time":1}},
{$group:{"_id":"$name","oldest":{$first:"$$ROOT"},
                       "youngest":{$last:"$$ROOT"}}}
])
_

o/p:

_{
        "_id" : "John",
        "oldest" : {
                "_id" : ObjectId("54da62dc7f9ac597d99c182d"),
                "name" : "John",
                "date_time" : ISODate("2014-06-11T19:16:46Z")
        },
        "youngest" : {
                "_id" : ObjectId("54da62dc7f9ac597d99c182e"),
                "name" : "John",
                "date_time" : ISODate("2015-06-11T19:16:46Z")
        }
}
_
5
BatScream