Tenho duas coleções mongo relacionadas. Esses documentos de exemplo ilustram sua relação:
// "things" collection example document:
{
_id: 1,
categories: [123, 234],
// other fields
}
// "categories" collection example documents:
{
_id: 123,
value: "Category name"
},
{
_id: 234,
value: "Other category name"
}
Estou tentando encontrar uma maneira de mapear os números de id no array categories de um documento things
para os valores dos documentos correspondentes na categories
coleção. Pelo exemplo acima, você acabaria com este documento:
{
_id: 1,
categories: [
"Category name",
"Other category name",
],
// other fields
}
Meu problema é que meu pipeline atual é excessivamente complicado e certamente executa operações desnecessárias, criando potenciais problemas de desempenho. Meu pipeline atual é:
- (ponto de partida)
{
_id: 1,
categories: [123, 234],
// other fields
}
$unwind
categorias
{
_id: 1,
categories: 123,
// other fields
},
{
_id: 1,
categories: 234,
// other fields
}
$lookup
na coleção de categorias que corresponde ao novo campo local "categorias" ao estrangeiro "_id"
{
_id: 1,
categories: [{ _id: 123, value: "Category name" }],
// other fields
},
{
_id: 1,
categories: [{ _id: 234, value: "Other category name" }],
// other fields
}
$addFields
com{ $arrayElemAt: [ "$categories", 0 ] }
para substituir a matriz pelo documento que eu queria em primeiro lugar
{
_id: 1,
categories: { _id: 123, value: "Category name" },
// other fields
},
{
_id: 1,
categories: { _id: 234, value: "Other category name" },
// other fields
}
$addFields
com{ categories: "$categories.value" }
para substituir o documento inteiro apenas pelo campo de valor
{
_id: 1,
categories: "Category name",
// other fields
},
{
_id: 1,
categories: "Other category name",
// other fields
}
$group
para "desfazer" o desenrolamento original. Estou usando_id: "$_id"
e{ $addToSet: "$categories" }
(e muitas outras propriedades no formato<field-name>: { $first: "$<field-name>" }
para adicionar novamente todos os "outros campos")
{
_id: 1,
categories: [
"Category name",
"Other category name",
],
// other fields
}
Estou preocupado em perder funções agregadas que são muito mais eficientes e, portanto, criar operações de leitura lentas e custosas quando eu usar isso em um grande número de documentos no futuro, mas não estou conseguindo encontrar soluções mais limpas. Qualquer empurrãozinho na direção certa seria muito apreciado.
por @cmgchess -
Tudo isso pode ser feito em duas etapas:
$lookup
(sem desenrolar)$set
usando$map
lucro. :)