MongoDB: поиск дубликатов по нескольким ключам

Документы относятся к типу

{
   "id": 1,
   "sig1": "12345",
   "sig2": "67890",
},
{
   "id": 2,
   "sig1": "67890",
   "sig2": "ABCDE",
},

Я хотел бы найти все значения, которые имеют один или несколько соответствующих документов, независимо от того, находится ли значение в sig1 или sig2. Таким образом, сопоставляются не только все документы с одинаковыми sig1 или sig2, но и два документа выше, поскольку sig2 первого совпадает с sig1 второго.

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

Я знаю, что агрегация для поиска дубликатов в одном поле выглядит так:

[
    {"$group" : { "_id": "$sig1", "count": { "$sum": 1 }, "docs": {"$push": "$id"} } },
    {"$match": {"_id" :{ "$ne" : "" } , "count" : {"$gt": 1} } },
]

Однако я изо всех сил пытаюсь совместить это с поиском по кросс-ключу/ИЛИ.

Использование JavaScript и MongoDB
Использование JavaScript и MongoDB
Сегодня я собираюсь вкратце рассказать о прототипах в JavaScript, а также представить и объяснить вам работу с базой данных MongoDB.
1
0
37
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я не знаю, насколько это будет эффективно с вашей коллекцией, но вот один из способов получить список "id" с общими значениями документов.

db.collection.aggregate([
  {
    "$set": {
      "valSet": {
        "$map": {
          "input": {
            "$objectToArray": "$$ROOT"
          },
          "in": {
            "$getField": {
              "field": "v",
              "input": "$$this"
            }
          }
        }
      }
    }
  },
  {
    "$unwind": "$valSet"
  },
  {
    "$group": {
      "_id": "$valSet",
      "ids": { "$push": "$id" }
    }
  },
  {
    "$match": {
      "$expr": { "$gt": [ { "$size": "$ids" }, 1 ] }
    }
  }
])

Пример вывода запроса:

[
  {
    "_id": "67890",
    "ids": [ 1, 2 ]
  }
]

Попробуйте на mongoplayground.net.

Если вы хотите ограничить поля только "sig1" и "sig2", вы можете использовать:

db.collection.aggregate([
  {
    "$set": {
      "valSet": [
        "$sig1",
        "$sig2"
      ]
    }
  },
  {
    "$unwind": "$valSet"
  },
  {
    "$group": {
      "_id": "$valSet",
      "ids": {
        "$push": "$id"
      }
    }
  },
  {
    "$match": {
      "$expr": {
        "$gt": [
          {
            "$size": "$ids"
          },
          1
        ]
      }
    }
  }
])

Попробуйте на mongoplayground.net.

Как ограничить его только полями sig1 и sig2? В моих документах может быть много несвязанных полей.

I hate JS 08.05.2022 12:54

@IhateJS Я обновил ответ дополнительным запросом, чтобы ограничить поля только "sig1" и "sig2".

rickhg12hs 08.05.2022 14:00

Другие вопросы по теме