Pengurangan peta memungkinkan Anda memproses kunci bernama, tetapi agregasi adalah cara yang tepat untuk kueri yang efisien.
Anda harus memodelkan data sebagai larik dokumen yang disematkan untuk kerangka kerja agregasi.
Saya telah memberi Anda dua opsi. Anda dapat mengujinya untuk kumpulan data Anda dan melihat mana yang bekerja lebih baik untuk Anda.
Sesuatu seperti
"v":[
{
"minute":1,
"seconds":[
{
"second":54,
"data":{
"field1":7.373158,
"entry_id":4635,
"field3":0.19,
"field2":88
}
}
]
},
{
"minute":2,
"seconds":...
}
]
Sekarang Anda dapat dengan mudah meminta item yang memiliki pembacaan sensor:"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"}}]
)
Atau, Anda dapat membagi dokumen berdasarkan menit. Sesuatu seperti
"v":[
{
"second":1,
"data":{
"field1":7.373158,
"entry_id":4635,
"field3":0.19,
"field2":88
}
},
{
"second":2,
"data":...
}
]
Anda sekarang dapat melakukan kueri seperti ( dengan indeks pada v.data.field1 )
db.col.aggregate(
[{"$match":{"v.data.field1":{"$gt":2}}},
{"$unwind":"$v"},
{"$match":{"v.data.field1":{"$gt":2}}},
{"$project":{"data":"$v.data"}}]
)
Anda dapat menanyakan item yang memiliki pembacaan sensor:"field1">2 dan "field3">5
Menggunakan struktur pertama
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"}}]
)
Menggunakan struktur kedua
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"}}]
)
Pembaruan Mongo 3.6
$match
dengan $expr
yang menerima ekspresi agregasi.
$gt > 0
- ekspresi agregasi untuk memeriksa di mana jumlah semua kriteria detik yang cocok dalam satu menit lebih besar dari 0
$objectToArray
untuk mengubah kunci bernama menjadi pasangan nilai kunci diikuti dengan $filter
detik pada kriteria input dan jumlah output dari catatan detik yang cocok.
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]
}
}})
Pembaruan Mongo 3.4 - Ganti $expr
dengan $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"
}
}})