フィルタリング部はまた、$group
_id
キーとそれに続く$match
パイプラインで使用するフィールドを作成するのに役立つ$addFields
パイプラインを使用して行うことができます。そのようなバックボーンは、$cond
演算子であり、これは、要求の条件を評価して所望の日付を生成する。
単一$redact
パイプラインで十分だろうが、あなたもで濾過文書グループにロジックを必要とするので、あなたにも、このようなロジックを持つフィールドを作成する$addFields
パイプラインを使用する場合があります。
次の例は、この概念を示しています。
db.sensors.aggregate([
{
"$addFields": {
"yearMonthDay": {
"$cond": [
{ /* check if date hour is less than 8 */
"$lt": [
{ "$hour": "$date" },
8
]
},
{ /* subtract one day from a measurement at < 08:00 */
"$dateToString": {
"format": "%Y-%m-%d",
"date": {
"$subtract": [
"$date",
1000 * 60 * 60 * 24
]
}
}
},
{ /* else return actual date */
"$dateToString": {
"format": "%Y-%m-%d",
"date": "$date"
}
}
]
},
"isNight": {
"$or": [
{ "$gte": [ { "$hour": "$date" }, 21 ] },
{ "$lt": [ { "$hour": "$date" }, 8 ] }
]
}
}
},
{ "$match": { "isNight": true } },
{
"$group": {
"_id": "$yearMonthDay",
"count": { "$sum": 1 }
}
}
])
、より詳細なアプローチは、(@Styvaneのおかげで)次のように$cond
の代わりに$switch
ケース式を使用することを含む:
db.sensors.aggregate([
{
"$addFields": {
"yearMonthDay": {
"$switch": {
"branches": [
{
"case": { "$lt": [ { "$hour": "$date" }, 8 ] },
"then": { /* subtract one day from a measurement at < 08:00 */
"$dateToString": {
"format": "%Y-%m-%d",
"date": {
"$subtract": [
"$date",
1000 * 60 * 60 * 24
]
}
}
}
},
{
"case": { "$gte": [ { "$hour": "$date" }, 8 ] },
"then": { /* return actual date */
"$dateToString": {
"format": "%Y-%m-%d",
"date": "$date"
}
}
}
]
}
},
"isNight": {
"$or": [
{ "$gte": [ { "$hour": "$date" }, 21 ] },
{ "$lt": [ { "$hour": "$date" }, 8 ] }
]
}
}
},
{ "$match": { "isNight": true } },
{
"$group": {
"_id": "$yearMonthDay",
"count": { "$sum": 1 }
}
}
])
'$ cond'ウィットを置き換えるのはどうですか? h '$ switch'? – styvane
同じことが実際にはOPがどのように冗長であるかに依存します。それ以外の場合、私は間違っていると私に正しい影響を与えることはないでしょう。 – chridam
あなたは正しいです、私はここでペタンティックにしようとしているわけではありませんが、あなたの意思を明確にし、MongoDB 3.4でこれをやっているのです。 – styvane