7

ホテルの happyHours を日時形式で保存しました。ここで、happyHours が現在の時刻よりも大きいすべてのホテルを取得したいと考えています。

私の知る限り、結果を取得するための日付比較があることはわかっていますが、これは日時オブジェクト全体を比較します。

時間だけを比較する方法はありますか?

データベース内の Happyhours 日付オブジェクトのサンプル:

"happyHours" : {
    "mon" : [ 
        {
            "startTime" : ISODate("2016-04-11T06:30:59.000Z"),
            "endTime" : ISODate("2016-04-11T14:30:59.000Z")
        }
    ],
    "tue" : [ 
        {
            "startTime" : ISODate("2016-04-11T06:30:59.000Z"),
            "endTime" : ISODate("2016-04-11T14:30:59.000Z")
        }
    ],
    "wed" : [ 
        {
            "startTime" : ISODate("2016-04-11T06:30:59.000Z"),
            "endTime" : ISODate("2016-04-11T14:30:59.000Z")
        }
    ],
    "thu" : [ 
        {
            "startTime" : ISODate("2016-04-11T06:30:59.000Z"),
            "endTime" : ISODate("2016-04-11T14:30:59.000Z")
        }
    ],
    "fri" : [ 
        {
            "startTime" : ISODate("2016-04-11T06:30:59.000Z"),
            "endTime" : ISODate("2016-04-11T14:30:59.000Z")
        }
    ],
    "sat" : [ 
        {
            "startTime" : ISODate("2016-04-11T06:30:59.000Z"),
            "endTime" : ISODate("2016-04-11T14:30:59.000Z")
        }
    ],
    "sun" : [ 
        {
            "startTime" : ISODate("2016-04-11T06:30:59.000Z"),
            "endTime" : ISODate("2016-04-11T14:30:59.000Z")
        }
    ]
}
4

1 に答える 1

5

まず、現在のスキーマはクエリに適していません。この場合、配列は実際には必要ありません。平日をキーとして保持する場合、より良いアプローチは、配列を失い、要素を参照することです。

"happyHours": {
    "mon": {
        "startTime" : ISODate("2016-04-11T06:30:59.000Z"),
        "endTime" : ISODate("2016-04-11T14:30:59.000Z")
    },
    ...
    "sun": {
        "startTime" : ISODate("2016-04-11T06:30:59.000Z"),
        "endTime" : ISODate("2016-04-11T14:30:59.000Z")
    }    
}

ただし、クエリをはるかに簡単にするはるかに優れた設計が必要です。happyHours次のように、フィールドを、曜日、開始時間、開始分、終了時間、および分をそれぞれ記述するドキュメントを保持する配列に変換できます。

"happyHours": [
    {
        "weekDay": "mon",
        "startHour": 6,
        "startMinutes": 30,
        "endHour": 14
        "endMinutes": 30
    }
    ...
]

クエリは次のようになります。

var now = new Date(),
    days = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sun'],
    weekDay = days[now.getDay()],
    hour = now.getHours(),
    minutes = now.getMinutes();

db.hotels.find({
    "happyHours.weekDay": weekDay,
    "happyHours.startHour": { "$lte": hour },
    "happyHours.startMinutes": { "$lte": minutes },
    "happyHours.endHour": { "$gte": hour },
    "happyHours.endMinutes": { "$gte": minutes }
})

上記の推奨事項に準拠するようにスキーマを変更する能力がない場合は、集約フレームワークが回避策を提供します。ステップで日付集計演算子を使用し、後続のパイプライン$projectでクエリを実行する次の集計パイプラインを検討してください。$match

 var now = new Date(),
    days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sun'],
    weekDay = days[now.getDay()],
    hour = now.getHours(),
    minutes = now.getMinutes();
    project = {
    "$project": {
        "otherfields": 1,
        "happyHours": 1,
        "happyHoursMonStartHour": { "$hour": "$happyHours.mon.startTime" },
        "happyHoursMonStartMinutes": { "$minute": "$happyHours.mon.startTime" },
        "happyHoursMonEndHour": { "$hour": "$happyHours.mon.endTime" },
        "happyHoursMonEndMinutes": { "$minute": "$happyHours.mon.endTime" },
        "happyHoursTueStartHour": { "$hour": "$happyHours.tue.startTime" },
        "happyHoursTueStartMinutes": { "$minute": "$happyHours.tue.startTime" },
        "happyHoursTueEndHour": { "$hour": "$happyHours.tue.endTime" },
        "happyHoursTueEndMinutes": { "$minute": "$happyHours.tue.endTime" },
        "happyHoursWedStartHour": { "$hour": "$happyHours.wed.startTime" },
        "happyHoursWedStartMinutes": { "$minute": "$happyHours.wed.startTime" },
        "happyHoursWedEndHour": { "$hour": "$happyHours.wed.endTime" },
        "happyHoursWedEndMinutes": { "$minute": "$happyHours.wed.endTime" },
        "happyHoursThuStartHour": { "$hour": "$happyHours.thu.startTime" },
        "happyHoursThuStartMinutes": { "$minute": "$happyHours.thur.startTime" },
        "happyHoursThuEndHour": { "$hour": "$happyHours.thu.endTime" },
        "happyHoursThuEndMinutes": { "$minute": "$happyHours.thu.endTime" },
        "happyHoursFriStartHour": { "$hour": "$happyHours.fri.startTime" },
        "happyHoursFriStartMinutes": { "$minute": "$happyHours.fri.startTime" },
        "happyHoursFriEndHour": { "$hour": "$happyHours.fri.endTime" },
        "happyHoursFriEndMinutes": { "$minute": "$happyHours.fri.endTime" },
        "happyHoursSatStartHour": { "$hour": "$happyHours.sat.startTime" },
        "happyHoursSatStartMinutes": { "$minute": "$happyHours.sat.startTime" },
        "happyHoursSatEndHour": { "$hour": "$happyHours.sat.endTime" },
        "happyHoursSatEndMinutes": { "$minute": "$happyHours.sat.endTime" },
        "happyHoursSunStartHour": { "$hour": "$happyHours.sun.startTime" },
        "happyHoursSunStartMinutes": { "$minute": "$happyHours.sun.startTime" },
        "happyHoursSunEndHour": { "$hour": "$happyHours.sun.endTime" },
        "happyHoursSunEndMinutes": { "$minute": "$happyHours.sun.endTime" },
    }
    },
    match = { "$match": {} },    
    pipeline = [
    { "$unwind": "$happyHours.mon" },
    { "$unwind": "$happyHours.tue" },
    { "$unwind": "$happyHours.wed" },
    { "$unwind": "$happyHours.thur" },
    { "$unwind": "$happyHours.fri" },
    { "$unwind": "$happyHours.sat" },
    { "$unwind": "$happyHours.sun" }    
    ];

match["$match"]["happyHours"+ weekDay +"StartHour"] = { "$lte": hour };
match["$match"]["happyHours"+ weekDay +"StartMinutes"] = { "$lte": minutes };
match["$match"]["happyHours"+ weekDay +"EndHour"] = { "$gte": minutes };
match["$match"]["happyHours"+ weekDay +"EndMinutes"] = { "$gte": minutes };
pipeline.push(project);
pipeline.push(match);

db.hotels.aggregate(pipeline);

パイプラインを実行する前に印刷すると、次のようにprintjson(pipeline)なります。

[
    {
        "$unwind" : "$happyHours.mon"
    },
    {
        "$unwind" : "$happyHours.tue"
    },
    {
        "$unwind" : "$happyHours.wed"
    },
    {
        "$unwind" : "$happyHours.thur"
    },
    {
        "$unwind" : "$happyHours.fri"
    },
    {
        "$unwind" : "$happyHours.sat"
    },
    {
        "$unwind" : "$happyHours.sun"
    },
    {
        "$project" : {
            "otherfields" : 1,
            "happyHours" : 1,
            "happyHoursMonStartHour" : {
                "$hour" : "$happyHours.mon.startTime"
            },
            "happyHoursMonStartMinutes" : {
                "$minute" : "$happyHours.mon.startTime"
            },
            "happyHoursMonEndHour" : {
                "$hour" : "$happyHours.mon.endTime"
            },
            "happyHoursMonEndMinutes" : {
                "$minute" : "$happyHours.mon.endTime"
            },
            "happyHoursTueStartHour" : {
                "$hour" : "$happyHours.tue.startTime"
            },
            "happyHoursTueStartMinutes" : {
                "$minute" : "$happyHours.tue.startTime"
            },
            "happyHoursTueEndHour" : {
                "$hour" : "$happyHours.tue.endTime"
            },
            "happyHoursTueEndMinutes" : {
                "$minute" : "$happyHours.tue.endTime"
            },
            "happyHoursWedStartHour" : {
                "$hour" : "$happyHours.wed.startTime"
            },
            "happyHoursWedStartMinutes" : {
                "$minute" : "$happyHours.wed.startTime"
            },
            "happyHoursWedEndHour" : {
                "$hour" : "$happyHours.wed.endTime"
            },
            "happyHoursWedEndMinutes" : {
                "$minute" : "$happyHours.wed.endTime"
            },
            "happyHoursThuStartHour" : {
                "$hour" : "$happyHours.thu.startTime"
            },
            "happyHoursThuStartMinutes" : {
                "$minute" : "$happyHours.thur.startTime"
            },
            "happyHoursThuEndHour" : {
                "$hour" : "$happyHours.thu.endTime"
            },
            "happyHoursThuEndMinutes" : {
                "$minute" : "$happyHours.thu.endTime"
            },
            "happyHoursFriStartHour" : {
                "$hour" : "$happyHours.fri.startTime"
            },
            "happyHoursFriStartMinutes" : {
                "$minute" : "$happyHours.fri.startTime"
            },
            "happyHoursFriEndHour" : {
                "$hour" : "$happyHours.fri.endTime"
            },
            "happyHoursFriEndMinutes" : {
                "$minute" : "$happyHours.fri.endTime"
            },
            "happyHoursSatStartHour" : {
                "$hour" : "$happyHours.sat.startTime"
            },
            "happyHoursSatStartMinutes" : {
                "$minute" : "$happyHours.sat.startTime"
            },
            "happyHoursSatEndHour" : {
                "$hour" : "$happyHours.sat.endTime"
            },
            "happyHoursSatEndMinutes" : {
                "$minute" : "$happyHours.sat.endTime"
            },
            "happyHoursSunStartHour" : {
                "$hour" : "$happyHours.sun.startTime"
            },
            "happyHoursSunStartMinutes" : {
                "$minute" : "$happyHours.sun.startTime"
            },
            "happyHoursSunEndHour" : {
                "$hour" : "$happyHours.sun.endTime"
            },
            "happyHoursSunEndMinutes" : {
                "$minute" : "$happyHours.sun.endTime"
            }
        }
    },
    {
        "$match" : {
            "happyHoursThuStartHour" : {
                "$lte" : 9
            },
            "happyHoursThuStartMinutes" : {
                "$lte" : 34
            },
            "happyHoursThuEndHour" : {
                "$gte" : 34
            },
            "happyHoursThuEndMinutes" : {
                "$gte" : 34
            }
        }
    }
]
于 2016-05-02T10:15:26.457 に答える