Met Map reduce kunt u benoemde sleutels verwerken, maar aggregatie is de beste manier voor efficiënte zoekopdrachten.
U moet de gegevens modelleren als een reeks ingesloten documenten voor een aggregatiekader.
Ik heb je twee opties gegeven. U kunt ze testen voor uw dataset en kijken welke het beste voor u werkt.
Iets als
"v":[
{
"minute":1,
"seconds":[
{
"second":54,
"data":{
"field1":7.373158,
"entry_id":4635,
"field3":0.19,
"field2":88
}
}
]
},
{
"minute":2,
"seconds":...
}
]
Nu kunt u eenvoudig zoeken naar items met sensoruitlezing:"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"}}]
)
U kunt de documenten ook per minuut splitsen. Iets als
"v":[
{
"second":1,
"data":{
"field1":7.373158,
"entry_id":4635,
"field3":0.19,
"field2":88
}
},
{
"second":2,
"data":...
}
]
U kunt nu een zoekopdracht uitvoeren zoals ( met index op v.data.field1 )
db.col.aggregate(
[{"$match":{"v.data.field1":{"$gt":2}}},
{"$unwind":"$v"},
{"$match":{"v.data.field1":{"$gt":2}}},
{"$project":{"data":"$v.data"}}]
)
U kunt items opvragen met sensoruitlezing:"field1">2 en "field3">5
Eerste structuur gebruiken
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"}}]
)
Tweede structuur gebruiken
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
met $expr
die aggregatie-expressie accepteert.
$gt > 0
- aggregatie-expressie om te controleren waar de som van alle overeenkomende secondencriteria in een minuut groter is dan 0
$objectToArray
om de genoemde sleutels om te zetten in een sleutelwaardepaar gevolgd door $filter
seconden op invoercriteria en uitvoernummer van overeenkomende secondenrecord.
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 - Vervang $expr
met $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"
}
}})