【MongoDB】月と日だけで日付レコードを検索するクエリの書き方
MongoDBで月と日だけを条件に日付を検索する方法
MongoDBでは、年に関係なく「月」や「日」だけを条件として日付型フィールドを検索したいケースがあります。そのような場合には、$where演算子を使用することで、JavaScriptの条件式を用いた柔軟な検索が可能です。
この記事では、実際にサンプルコレクションを作成しながら、月と日を指定した検索クエリの書き方をわかりやすく解説します。
サンプルコレクションの作成
まずは、「ShippingDate(出荷日)」フィールドを持つドキュメントを4件登録したコレクションを作成しましょう。
> db.demo181.insertOne({"ShippingDate":new ISODate("2020-01-10")});
{
"acknowledged" : true,
"insertedId" : ObjectId("5e398a699e4f06af551997fe")
}
> db.demo181.insertOne({"ShippingDate":new ISODate("2019-12-11")});
{
"acknowledged" : true,
"insertedId" : ObjectId("5e398a729e4f06af551997ff")
}
> db.demo181.insertOne({"ShippingDate":new ISODate("2018-01-10")});
{
"acknowledged" : true,
"insertedId" : ObjectId("5e398a7d9e4f06af55199800")
}
> db.demo181.insertOne({"ShippingDate":new ISODate("2020-10-12")});
{
"acknowledged" : true,
"insertedId" : ObjectId("5e398a879e4f06af55199801")
}find()で登録済みドキュメントを確認する
find()メソッドを使うと、コレクション内のすべてのドキュメントを表示できます。
> db.demo181.find();
上記のコマンドを実行すると、以下のような出力が得られます。
{ "_id" : ObjectId("5e398a699e4f06af551997fe"), "ShippingDate" : ISODate("2020-01-10T00:00:00Z") }
{ "_id" : ObjectId("5e398a729e4f06af551997ff"), "ShippingDate" : ISODate("2019-12-11T00:00:00Z") }
{ "_id" : ObjectId("5e398a7d9e4f06af55199800"), "ShippingDate" : ISODate("2018-01-10T00:00:00Z") }
{ "_id" : ObjectId("5e398a879e4f06af55199801"), "ShippingDate" : ISODate("2020-10-12T00:00:00Z") }月と日を指定した$whereクエリの実行
続いて、本題となる「月と日のみを条件とした検索クエリ」です。$whereの中で関数を定義し、getMonth()で月を、getDate()で日を取得して比較します。
> db.demo181.find({$where : function() { return this.ShippingDate.getMonth() == 1 || this.ShippingDate.getDate() == 10} })このクエリを実行すると、次の2件のドキュメントが該当として返されます。
{ "_id" : ObjectId("5e398a699e4f06af551997fe"), "ShippingDate" : ISODate("2020-01-10T00:00:00Z") }
{ "_id" : ObjectId("5e398a7d9e4f06af55199800"), "ShippingDate" : ISODate("2018-01-10T00:00:00Z") }どちらも「日付が10日」のレコードであり、OR条件(||)によって一致していることがわかります。
注意点:getMonth()は0始まり
JavaScriptのgetMonth()メソッドは0始まりで月を返す点に注意が必要です。つまり、1月なら「0」、2月なら「1」という値になります。暦上の月(1〜12)で比較したい場合は、「getMonth() + 1」のように1を加えるか、「getMonth() == 対象の月 − 1」として指定してください。
より効率的な代替手段:$exprと集計演算子
$whereは各ドキュメントごとにJavaScriptを実行するため、ドキュメント数が多いコレクションではパフォーマンスが低下しやすいという欠点があります。MongoDB 3.6以降を使用している場合は、$exprと集計演算子($month、$dayOfMonth)を組み合わせる方法がおすすめです。
> db.demo181.find({ $expr: { $or: [
{ $eq: [ { $month: "$ShippingDate" }, 1 ] },
{ $eq: [ { $dayOfMonth: "$ShippingDate" }, 10 ] }
] } })こちらの方法であれば、JavaScriptの実行オーバーヘッドを避けつつ、同じ条件での検索が可能です。$monthは1始まり(1月=1)で月を返すため、直感的に条件を記述できるのもメリットです。
まとめ
- 月や日だけを条件に検索するには、$whereでJavaScript関数を利用できる
- getMonth()は0始まりなので、暦の月と比較する際は注意が必要
- データ量が多い場合は、$expr+$month/$dayOfMonthの方が高速で推奨される
用途やデータ規模に応じて、これらの方法を使い分けてください。
-
MySQLで現在の日付の月・日と比較してレコードを取得する方法
はじめにMySQLで、現在の日付の「月」と「日」が一致するレコードだけを抽出したいケースはよくあります。例えば、記念日や誕生日のように年に関係なく同じ日付のデータを取得したい場合に便利です。このような場合には、MONTH()関数とDAY()関数を組み合わせて使用します。ここでは、実際にテーブルを作成し、データを挿入して、現在の日付と月日を比較してレコードを取得する手順を解説します。サンプルテーブルの作成まず、記念日を格納するテーブルを作成します。mysql> create table DemoTable1429 -> ( &n
-
【MySQL】日付レコードから曜日を減算し、曜日名とともに結果を表示する方法
はじめにMySQLで保存された日付レコードから、その週の開始日(月曜日)を計算して減算し、曜日名とともに結果を表示したい場合があります。このような処理には DATE_FORMAT() 関数を使用します。SUBDATE() と WEEKDAY() を組み合わせることで、各日付が属する週の月曜日の日付を「Mon 19 Oct」のような形式で取得できます。以下、具体的な手順をサンプルコードとともに解説します。1. テーブルの作成まず、日付を文字列として格納するテーブルを作成します。mysql> create table DemoTable1820 ( AdmissionDate