I have a mongo collection (tables) that has documents of the form:
{
"tableName": "Items",
"rows": [
{
"label": "row 1 label here",
"items": ["item1", "item2", "item3"]
},
{
"label": "row 2 label here",
"items": ["item4", "item5", "item6"]
}
]
}
And I have another collection (items) that has documents of the form:
{
"id": "item1",
"name": "Item name",
"code": "XXX-XXXX-XXXX",
"price": 100
}
Now I want to query all items in a given table, so I am using the following aggregation:
{
"$lookup": {
from: "items",
localField: "rows.items",
foreignField: "id",
as: "rows.items"
}
}
So I am expecting all of "item1", "item2", … to be replaced with their corresponding documents as such:
{
"tableName": "Items",
"rows": [
{
"label": "row 1 label here",
"items": [
{
"id": "item1",
"name": "Item name",
"code": "XXX-XXXX-XXXX",
"price": 100
},
... // the rest of the items
]
},
... // the rest of the rows
]
}
But instead, "rows" is returned as an object, containing only the first object in the expected array, and the label field is even gone:
{
"tableName": "Items",
"rows": { // <-- rows is returned as on object, should be array
"items": [ // <-- the "label" field is missing
{
"id": "item1",
"name": "Item name",
"code": "XXX-XXXX-XXXX",
"price": 100
},
... // the rest of the items
]
}
}
So how do I preserve the outer array and the missing fields?
2
Answers
This is the reason why I am personally against the usage of nested arrays. It introduces unnecessary complexity to the queries.
You may need to
$unwind
twice atrows
androws.items
level to flatten the arrays. Perform the$lookup
and$mergeObjects
with the lookup result. You will then need to do 2$group
to revert back to your original structure.Mongo Playground
If you find yourself working at
rows.items
level frequently, consider refactoring the schema to store the entries as individual documents like this. You can gain potential performance boost through indexing too.Another option is to avoid
$unwind
and$group
back, and replace them with$reduce
and$map
:See how it works on the playground example