Map Reduceを使用すると、名前付きキーを処理できますが、集約は効率的なクエリを実現する方法です。
集約フレームワークの埋め込みドキュメントの配列としてデータをモデル化する必要があります。
私はあなたに2つのオプションを提供しました。データセットに対してそれらをテストし、どちらがより適切に機能するかを確認できます。
のようなもの
"v":[
{
"minute":1,
"seconds":[
{
"second":54,
"data":{
"field1":7.373158,
"entry_id":4635,
"field3":0.19,
"field2":88
}
}
]
},
{
"minute":2,
"seconds":...
}
]
これで、センサーの読み取り値が「field1」>2のアイテムを簡単に照会できます。
db.col.aggregate(
[{"$match":{"v.seconds.data.field1":{"$gt":2}}},
{"$unwind":"$v"},
{"$match":{"v.seconds.data.field1":{"$gt":2}}},
{"$unwind":"$v.seconds"},
{"$match":{"v.seconds.data.field1":{"$gt":2}}},
{"$project":{"data":"$v.seconds.data"}}]
)
または、ドキュメントを分単位で分割することもできます。のようなもの
"v":[
{
"second":1,
"data":{
"field1":7.373158,
"entry_id":4635,
"field3":0.19,
"field2":88
}
},
{
"second":2,
"data":...
}
]
これで、次のようにクエリを実行できます(v.data.field1のインデックスを使用)
db.col.aggregate(
[{"$match":{"v.data.field1":{"$gt":2}}},
{"$unwind":"$v"},
{"$match":{"v.data.field1":{"$gt":2}}},
{"$project":{"data":"$v.data"}}]
)
センサーの読み取り値が「field1">2」および「field3">5
」のアイテムをクエリできます。最初の構造を使用する
db.col.aggregate(
[{"$match":{"v":{"$elemMatch":{"seconds": {$elemMatch:{"field1":{$gt":2},"field3":{$gt":5}}}}}}},
{"$unwind":"$v"},
{"$match":{"v.seconds": {$elemMatch:{"field1":{$gt":2},"field3":{$gt":5}}}}},
{"$unwind":"$v.seconds"},
{"$project":{"data":"$v.seconds.data"}}]
)
2番目の構造を使用する
db.col.aggregate(
[{"$match":{"v.data":{$elemMatch:{"field1":{$gt":2},"field3":{$gt":5}}}}},
{"$unwind":"$v"},
{"$match":{"v.data.field1":{"$gt":2},"v.data.field3":{"$gt":5} }},
{"$project":{"data":"$v.data"}}]
)
Mongo Update 3.6
$match
$expr
を使用 集計式を受け入れます。
$gt > 0
-1分間に一致するすべての秒基準の合計が0より大きい場所をチェックする集計式
$objectToArray
名前付きキーをキーと値のペアに変換し、その後に$filter
を続けます 入力基準の秒数と一致する秒数のレコードを出力します。
db.testcol.aggregate(
{"$match":{
"$expr":{
"$gt":[
{"$sum":{
"$map":{
"input":{"$objectToArray":"$v"},
"as":"secondsofminute",
"in":{
"$size":{
"$filter":{
"input":{"$objectToArray":"$$secondsofminute.v"},
"as":"seconds",
"cond":{"$gt":["$$seconds.v.field2",2]}
}
}
}
}
}},
0]
}
}})
Mongo Update 3.4-$expr
を置き換えます $redact
を使用
db.col.aggregate(
{"$redact":{
"$cond":{
"if":{
"$gt":[
{"$sum":{
"$map":{
"input":{"$objectToArray":"$v"},
"as":"secondsofminute",
"in":{
"$size":{
"$filter":{
"input":{"$objectToArray":"$$secondsofminute.v"},
"as":"seconds",
"cond":{"$gt":["$$seconds.v.field2",2]}
}
}
}
}
}},
0]
},
"then":"$$KEEP",
"else":"$$PRUNE"
}
}})