Reputation: 33
I'm converting an array to a map in mongo.
"items":[
{
"id":"AB-02",
"qty":2
},
{
"id":"AB-03",
"qty":0
},
{
"id":"AB-03",
"qty":9
}
]
becomes
"items":{
"AB-02":{
"id":"AB-02",
"qty":2
},
"AB-03":{
"id":"AB-03",
"qty":0
},
"AB-04":{
"id":"AB-03",
"qty":9
}
}
in the array version, it's quite easy to query based on how many elements inside items
, but how do I do that with the latter format of items
? as in, to query those documents whose items
has lets say 7 elements?
Upvotes: 3
Views: 1968
Reputation: 103365
From MongoDB 3.4.4 and above, you can use the $arrayToObject
operator that transforms an array into a single document and the array should be a list of documents that contains two fields, k
and v
where:
The
k
field contains the field name.The
v
field contains the value of the field.
So you would need to create a pipeline that first transforms items
array from
"items":[
{
"id":"AB-02",
"qty":2
},
{
"id":"AB-03",
"qty":0
},
{
"id":"AB-03",
"qty":9
}
]
to
"items" : [
{
"k" : "AB-02",
"v" : {
"id" : "AB-02",
"qty" : 2.0
}
},
{
"k" : "AB-03",
"v" : {
"id" : "AB-03",
"qty" : 0.0
}
},
{
"k" : "AB-03",
"v" : {
"id" : "AB-03",
"qty" : 9.0
}
}
]
$map
correctly does that with the expression
"$map": {
"input": "$items",
"as": "item",
"in": {
"k": "$$item.id",
"v": "$$item"
}
}
So your final pipeline can wrap all the above operators into a single stage with $addFields
as:
db.collection.aggregate([
{
"$addFields": {
"items": {
"$arrayToObject": {
"$map": {
"input": "$items",
"as": "item",
"in": {
"k": "$$item.id",
"v": "$$item"
}
}
}
}
}
}
])
Upvotes: 4