У меня есть пример данных, как это:
[
{ objectId: 1, user: 1, phones: [1, 2], emails: ['a'] },
{ objectId: 2, user: 1, phones: [1, 5], emails: ['a', 'f'] },
{ objectId: 3, user: 1, phones: [8, 9], emails: ['f', 'g'] },
{ objectId: 4, user: 1, phones: [10], emails: ['h'] },
{ objectId: 5, user: 2, phones: [1, 2, 3], emails: ['aa', 'bb', cc'] },
]
Теперь мне нужно объединить все связанные строки в одну при следующих условиях:
- У того же пользователя
- Иметь хотя бы один общий телефон или электронную почту
Итак, выведите что-то вроде этого:
[
{ objectId: 1, user: 1, phones: [1, 2, 5, 8, 9], emails: ['a', 'f', 'g'] },
{ objectId: 4, user: 1, phones: [10], emails: ['h'] },
{ objectId: 5, user: 2, phones: [1, 2, 3], emails: ['aa', 'bb', cc'] },
]
Это то, что я придумал до сих пор:
[
{
$unwind: {
path: "$phones",
preserveNullAndEmptyArrays: true
}
},
{
$group: {
_id: {
user: "$user",
phone: "$phones"
},
objectIds: {
$addToSet: "$_id"
},
emailsList: {
$push: "$emails"
},
user: { $first: "$user" },
phones: {
$first: "$phones"
}
}
},
{
"$addFields": {
"emails": {
"$reduce": {
"input": "$emailsList",
"initialValue": [],
"in": { "$setUnion": ["$$value", "$$this"] }
}
}
}
},
{
"$project": {
"emailsList": 0
}
},
{
$unwind: {
path: "$emails",
preserveNullAndEmptyArrays: true
}
},
{
$group: {
_id: {
user: "$user",
phone: "$emails"
},
objectIdsList: {
$push: "$objectIds"
}
}
},
{
"$project": {
"mergedObjectIds": {
"$reduce": {
"input": "$objectIdsList",
"initialValue": [],
"in": { "$setUnion": ["$$value", "$$this"] }
}
}
}
}
]
И затем у нас есть список объектных идентификаторов, которые необходимо объединить, тогда я объединю все это в коде приложения. Так что в любом случае я могу сделать это в одной структуре агрегации или передать результат этого агрегата следующему