Есть несколько шагов для получения нужных вам результатов. Мы собираемся написать агрегированный конвейер, чтобы выполнить работу.
Сначала вам нужно развернуть значения массива следующим образом:
{
$unwind: "$contacts"
}
Do c: https://docs.mongodb.com/manual/reference/operator/aggregation/unwind/
Это приведет к:
[
{
"_id": ObjectId("5a934e000102030405000000"),
"contacts": {
"name": "john",
"phone": "123456"
},
"name": "david"
},
{
"_id": ObjectId("5a934e000102030405000000"),
"contacts": {
"name": "george",
"phone": "0987654"
},
"name": "david"
},
{
"_id": ObjectId("5a934e000102030405000001"),
"contacts": {
"name": "harry",
"phone": "123456"
},
"name": "anita"
},
{
"_id": ObjectId("5a934e000102030405000001"),
"contacts": {
"name": "kurita",
"phone": "323434"
},
"name": "anita"
}
]
Нам будет намного проще группировать по полям.
Do c: https://docs.mongodb.com/manual/reference/operator/aggregation/group/
{
$group: {
_id: {
phone: "$contacts.phone"
},
name: {
$addToSet: "$name"
},
contacts: {
$addToSet: "$contacts.name"
},
count: {
$sum: 1
}
}
}
Это дает следующий результат:
[
{
"_id": {
"phone": "323434"
},
"contacts": [
"kurita"
],
"count": 1,
"name": [
"anita"
]
},
{
"_id": {
"phone": "123456"
},
"contacts": [
"john",
"harry"
],
"count": 2,
"name": [
"david",
"anita"
]
},
{
"_id": {
"phone": "0987654"
},
"contacts": [
"george"
],
"count": 1,
"name": [
"david"
]
}
]
На основе результата нам нужно сопоставить число больше 1, например:
Do c: https://docs.mongodb.com/manual/reference/operator/aggregation/match/
{
$match: {
count: {
"$gt": 1
}
}
}
Результат:
[
{
"_id": {
"phone": "123456"
},
"contacts": [
"john",
"harry"
],
"count": 2,
"name": [
"david",
"anita"
]
}
]
Запрос будет выглядеть так:
Do c: https://docs.mongodb.com/manual/reference/operator/aggregation-pipeline/
db.collection.aggregate([
{
$unwind: "$contacts"
},
{
$group: {
_id: {
phone: "$contacts.phone"
},
name: {
$addToSet: "$name"
},
contacts: {
$addToSet: "$contacts.name"
},
count: {
$sum: 1
}
}
},
{
$match: {
count: {
"$gt": 1
}
}
}
])
MongoPlayground: https://mongoplayground.net/p/qSvhcYyAcQO
Надеюсь, это даст вам небольшое представление о том, что возможно с конвейером агрегации.
Обновление / исправление В соответствии с вашими требованиями вы должны sh иметь 2 объекта с именем foreach с дублирующимися контактами, тогда вы можете использовать unwind снова после матча.
[
{
"_id": {
"phone": "123456"
},
"contacts": [
"harry",
"john"
],
"count": 2,
"name": "david"
},
{
"_id": {
"phone": "123456"
},
"contacts": [
"harry",
"john"
],
"count": 2,
"name": "anita"
}
]
ура, Кевин