La réduction de carte vous permet de traiter des clés nommées, mais l'agrégation est la voie à suivre pour des requêtes efficaces.
Vous devez modéliser les données sous forme de tableau de documents intégrés pour le cadre d'agrégation.
Je vous ai proposé deux options. Vous pouvez les tester pour votre ensemble de données et voir lequel fonctionne le mieux pour vous.
Quelque chose comme
"v":[
{
"minute":1,
"seconds":[
{
"second":54,
"data":{
"field1":7.373158,
"entry_id":4635,
"field3":0.19,
"field2":88
}
}
]
},
{
"minute":2,
"seconds":...
}
]
Désormais, vous pouvez facilement interroger les éléments qui ont une lecture de capteur :"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"}}]
)
Alternativement, vous pouvez diviser les documents par minute. Quelque chose comme
"v":[
{
"second":1,
"data":{
"field1":7.373158,
"entry_id":4635,
"field3":0.19,
"field2":88
}
},
{
"second":2,
"data":...
}
]
Vous pouvez maintenant interroger comme (avec index sur v.data.field1)
db.col.aggregate(
[{"$match":{"v.data.field1":{"$gt":2}}},
{"$unwind":"$v"},
{"$match":{"v.data.field1":{"$gt":2}}},
{"$project":{"data":"$v.data"}}]
)
Vous pouvez interroger les éléments qui ont une lecture de capteur :"field1">2 et "field3">5
Utilisation de la première structure
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"}}]
)
Utilisation de la seconde structure
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 Mise à jour 3.6
$match
avec $expr
qui accepte l'expression d'agrégation.
$gt > 0
- expression d'agrégation pour vérifier où la somme de tous les critères de secondes correspondants dans une minute est supérieure à 0
$objectToArray
pour convertir les clés nommées en paire clé-valeur suivie de $filter
secondes sur les critères d'entrée et sortie du nombre d'enregistrements de secondes correspondants.
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 - Remplacer $expr
avec $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"
}
}})