Tenho estas duas coleções do MongoDB:
Coleção A
{ "_id": 1, "field1": "A", "field2": "", "value": 42 }
{ "_id": 2, "field1": "B", "field2": "", "value": 99 }
{ "_id": 3, "field1": "C", "field2": "", "value": 15 }
{ "_id": 4, "field1": "C", "field2": "Z", "value": 15 }
Coleção B
{ "_id": 1, "field1": "A", "field2": "", "arrayField": [10, 42, 73] }
{ "_id": 2, "field1": "B", "field2": "", "arrayField": null }
{ "_id": 3, "field1": "C", "field2": "", "arrayField": null }
{ "_id": 4, "field1": "C", "field2": "Z", "arrayField": [99, 15] }
Preciso unir B em A com base em field1
, field2
e value
- arrayField
; os dois primeiros sempre precisam corresponder, mas a terceira condição só é necessária quando arrayField
não está vazia, caso contrário, os documentos podem ser desambiguados pelos dois primeiros. Foi a isso que cheguei trabalhando no Compass:
[
{
$lookup: {
from: "Collection B",
let: {
value: "$value",
field1: "$field1",
field2: "$field2"
},
pipeline: [
{
$match: {
$expr: {
$and: [
{$eq: ["$field1","$$field1"]},
{$eq: ["$field2","$$field2"]},
{$cond: [
{$ifNull: ["$arrayField",false]},
{$in: ["$$value","$arrayField"]},
true
]}
]
}
}
}
],
as: "result"
}
}
]
Isso é bem próximo, mas só corresponde a documentos em B onde o arrayField
NÃO está vazio. Correspondências simples entre os outros dois campos são ignoradas. Como posso evitar esse comportamento? Muito obrigado antecipadamente por qualquer conselho.
Na verdade, você está bem perto, em termos de identificar o caso nulo no comentário. Você só precisa envolvê-lo com
$ifNull
para retornar tanto o caso nulo quanto o caso de campo inexistente para ambos os arrays vazios e verificar o tamanho do array.Repostagem do playground no comentário:
Parque infantil Mongo