MongoDBで範囲内の日付レコード(ISODate形式)を取得するクエリの書き方
はじめに
MongoDBでISODate形式の日付データを扱う際、「特定の時刻範囲に該当するレコードだけを抽出したい」というケースはよくあります。本記事では、$redact演算子と$hour演算子を組み合わせて、日付の時刻部分を条件にドキュメントを取得する方法を、実際のコード例とともに解説します。
サンプルコレクションの作成
まず、ISODate形式のDueDateフィールドを持つドキュメントを格納したコレクションを作成します。
> db.demo178.insertOne({"DueDate":new ISODate("2019-01-10T06:18:20.474Z")});
{
"acknowledged" : true,
"insertedId" : ObjectId("5e397bd89e4f06af551997f5")
}
> db.demo178.insertOne({"DueDate":new ISODate("2020-11-10T18:05:11.474Z")});
{
"acknowledged" : true,
"insertedId" : ObjectId("5e397bf39e4f06af551997f6")
}
> db.demo178.insertOne({"DueDate":new ISODate("2020-03-15T07:05:10.474Z")});
{
"acknowledged" : true,
"insertedId" : ObjectId("5e397c039e4f06af551997f7")
}
> db.demo178.insertOne({"DueDate":new ISODate("2020-06-11T16:05:10.474Z")});
{
"acknowledged" : true,
"insertedId" : ObjectId("5e397c0f9e4f06af551997f8")
}
登録済みドキュメントの確認
find()メソッドを使えば、コレクション内のすべてのドキュメントを表示できます。
> db.demo178.find();
実行結果は以下の通りです。合計4件のドキュメントが登録されています。
{ "_id" : ObjectId("5e397bd89e4f06af551997f5"), "DueDate" : ISODate("2019-01-10T06:18:20.474Z") }
{ "_id" : ObjectId("5e397bf39e4f06af551997f6"), "DueDate" : ISODate("2020-11-10T18:05:11.474Z") }
{ "_id" : ObjectId("5e397c039e4f06af551997f7"), "DueDate" : ISODate("2020-03-15T07:05:10.474Z") }
{ "_id" : ObjectId("5e397c0f9e4f06af551997f8"), "DueDate" : ISODate("2020-06-11T16:05:10.474Z") }
時刻の範囲でレコードを抽出するクエリ
ここでは、DueDateの時刻が「5時より大きく9時未満」であるドキュメントのみを取得します。以下がそのクエリです。
> db.demo178.aggregate([
...{
... "$redact": {
... "$cond": {
... "if": {
... "$and": [
... { "$gt": [ {"$hour": "$DueDate"}, 5] },
... { "$lt": [ {"$hour": "$DueDate"}, 9] }
... ]
... },
... "then": "$$KEEP",
... "else": "$$PRUNE"
... }
... }
... }
...])
クエリのポイント解説
- $hour:日付フィールドから「時」(0〜23の整数)を取り出します。
- $and / $gt / $lt:「時が5より大きい」かつ「時が9より小さい」という複合条件を構築します。
- $redact:条件を満たすドキュメントは
$$KEEPで保持し、満たさないものは$$PRUNEで除外します。
実行すると、次のような出力が得られます。条件に合致する2件のドキュメントだけが表示されていることが確認できます。
{ "_id" : ObjectId("5e397bd89e4f06af551997f5"), "DueDate" : ISODate("2019-01-10T06:18:20.474Z") }
{ "_id" : ObjectId("5e397c039e4f06af551997f7"), "DueDate" : ISODate("2020-03-15T07:05:10.474Z") }
まとめ
このように、集計パイプラインの$redactと日付演算子を組み合わせることで、ISODate形式のデータから時刻の範囲に基づいた柔軟な絞り込みが可能になります。単純な日付比較なら$matchで十分ですが、日付の一部(時・分など)を直接評価したい場合には、本記事のような$redactを使った手法が非常に有効です。
-
【MongoDB】特定のフィールド(キー)を持つドキュメントだけを抽出する$exists演算子の使い方
MongoDBでは、特定のフィールド(キー)を持つドキュメントだけを抽出したいケースがよくあります。たとえば、一部のドキュメントにしか存在しない項目を条件に検索する場合です。そんなときに便利なのが $exists 演算子です。 $exists演算子の基本構文 指定したフィールドが存在するレコードを選択するには、次のような構文を使用します。 db.yourCollectionName.find( { yourFieldName: { $exists : true } } ).pretty(); この構文を実際に確認できるよう、サンプルコレクションを作成してみましょう。 サンプルデータの作成 まず
-
MongoDBでDate/ISODateの各コンポーネント(年・月・日・時・分・秒)を取得する方法
MongoDBでDate(ISODate)の各コンポーネント(年・月・日・時・分・秒など)を取得するには、まずコレクションに日付を含むドキュメントを作成します。ここでは、実際のコード例を通して手順をわかりやすく解説します。1. 日付を含むドキュメントの作成まず、insert()メソッドを使って、現在日時を持つドキュメントをコレクションに挿入します。> db.componentOfDateDemo.insert({"ShippingDate":new Date()}); WriteResult({ "nInserted" : 1 })2. find(