как найти дублирующее значение массива в документе mongodb - PullRequest
0 голосов
/ 15 февраля 2020

У меня вопрос, возможно, многие из вас могут мне помочь.

, поэтому у меня есть данные на mongodb.

первые данные

 {
    "name" : 'david'
    contacts : [
    {
    "name" : 'john',
    "phone" : '123456'
    },
    {
    "name" : 'george',
    "phone" : '0987654'
    }
    ]
    }

вторые данные

{
    "name" : 'anita',
    "contacts" : [
    {
    "name" : 'harry',
    "phone" : '123456'
    },
    {
    "name" : 'kurita',
    "phone" : '323434'
    }
    ]
    }

проблема в том, могу ли я запросить данные с дубликатом contacts.phone. так что результат покажет как это.

{
"name" : 'david',
"contacts" : [
{
"name" : 'john',
"phone" : '123456'
}
]
}

{
"name" : 'anita',
"contacts" : [
{
"name" : 'harry',
"phone" : '123456'
}
]
}

данные Джон и Анита покажут, потому что у них есть аналогичные данные по контактам. все понимают, о чем я.

большое спасибо

1 Ответ

0 голосов
/ 15 февраля 2020

Есть несколько шагов для получения нужных вам результатов. Мы собираемся написать агрегированный конвейер, чтобы выполнить работу.

Сначала вам нужно развернуть значения массива следующим образом:

{
    $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"
    }
]

ура, Кевин

...