javascript - MongoDB Match and Slice multiple child arrays -
i have schema
var dataschema = new schema({ hid: { type: string }, sensors: [{ nid: { type: string }, sid: { type: string }, data: { param1: { type: string }, param2: { type: string }, data: { type: string } }, date: { type: date, default: date.now } }], actuators: [{ nid: { type: string }, aid: { type: string }, control_id: { type: string }, data: { param1: { type: string }, param2: { type: string }, data: { type: string } }, date: { type: date, default: date.now } }], status: [{ nid: {type: string}, status_code: {type: string}, date: { type: date, default: date.now } }], updated: { type: date, default: date.now }, created: { type: date } });
the query i'm trying build should search schema "hid", pick "sensors", "actuators" , "status" arrays objects match nid
provide , limit result 10 element each array.
actually, don't use multiple pipeline phases when "one" do. every pipeline stage include adding "time" processing since it's pass through data.
so logically works in "single" stage, should stay in "single" stage:
data.aggregate([ { "$match": { "hid": hid } }, { "$project": { "sensors": { "$slice": [ { "$filter": { "input": "$sensors", "as": "sensor", "cond": { "$eq": [ "$$sensor.nid", nid ] } }}, -10 ] }, "actuators": { "$slice": [ { "$filter": { "input": "$actuators", "as": "actuator", "cond": { "$eq": [ "$$actuator.nid", nid ] } }}, -10 ] }, "status": { "$slice": [ { "$filter": { "input": "$status", "as": "status", "cond": { "$eq": [ "$$status.nid", nid ] } }}, -10 ] }, "updated": 1, "created": 1 }} ])
also, it's not necessary use "_id": 1
in inclusions since "_id"
always included unless explicitly "excluded".
the main case try not create unnecessary stages, since it's bad performance. indicators of are:
$project
followed$project
, means can in 1 stage.$project
followed$group
going compacted "optimizer" anyway, "should" in habit of of combining two.$project
followed$match
, should indicate should using$redact
in single stage instead. since did$project
produce fields based on calculations, considered in$match
.
and finally:
$unwind
before$match
, should have been$filter
in$project
"before"$unwind
. since in fact work lot faster "filter" within document, , saves cost on processing$unwind
, due less output filtered content.
but 1 more:
all of "array" operations such
$map
,$filter
,$slice
, "set operators" should used "in-line" each other, in cases manipulating same array content. same applies wrapping$sum
or$max
these can work directly on arrays themselves, , strange looking effective:{ "$sum": { "$sum": "$array" } }
structure within
$group
stage.
Comments
Post a Comment