Mit Map Reduce können Sie benannte Schlüssel verarbeiten, aber Aggregation ist der richtige Weg für effiziente Abfragen.
Sie müssen die Daten als Array eingebetteter Dokumente für das Aggregationsframework modellieren.
Ich habe Ihnen zwei Optionen zur Verfügung gestellt. Sie können sie für Ihren Datensatz testen und sehen, welche für Sie besser funktioniert.
So etwas wie
"v":[
{
"minute":1,
"seconds":[
{
"second":54,
"data":{
"field1":7.373158,
"entry_id":4635,
"field3":0.19,
"field2":88
}
}
]
},
{
"minute":2,
"seconds":...
}
]
Jetzt können Sie ganz einfach nach Artikeln suchen, die einen Sensorwert haben:"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"}}]
)
Alternativ können Sie die Dokumente minutenweise aufteilen. So etwas wie
"v":[
{
"second":1,
"data":{
"field1":7.373158,
"entry_id":4635,
"field3":0.19,
"field2":88
}
},
{
"second":2,
"data":...
}
]
Sie können jetzt wie (mit Index auf v.data.field1)
abfragendb.col.aggregate(
[{"$match":{"v.data.field1":{"$gt":2}}},
{"$unwind":"$v"},
{"$match":{"v.data.field1":{"$gt":2}}},
{"$project":{"data":"$v.data"}}]
)
Sie können Elemente mit Sensorwerten abfragen:"field1">2 und "field3">5
Verwendung der ersten Struktur
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"}}]
)
Zweite Struktur verwenden
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
mit $expr
die einen Aggregationsausdruck akzeptiert.
$gt > 0
- Aggregationsausdruck, um zu prüfen, wo die Summe aller übereinstimmenden Sekundenkriterien in einer Minute größer als 0 ist
$objectToArray
um die benannten Schlüssel in Schlüsselwertpaare gefolgt von $filter
umzuwandeln Sekunden auf Eingabekriterien und Ausgabe Nr. des übereinstimmenden Sekunden-Datensatzes.
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 – Ersetzen Sie $expr
mit $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"
}
}})