Навигация

    Shopker - Форум

    • Зарегистрироваться
    • Войти
    • Поиск
    • Категории
    • Последние
    • Метки
    • Популярные
    • Пользователи
    • Группы
    • Вернуться на сайт

    MongoDB: поиск ассиметричных записей

    Вопросы и обсуждения
    2
    5
    234
    Загружаем больше сообщений
    • Сначала старые
    • Сначала новые
    • По количеству голосов
    Ответить
    • Ответить, создав новую тему
    Авторизуйтесь, чтобы ответить
    Эта тема была удалена. Только пользователи с правом управления темами могут её видеть.
    • L
      LA отредактировано Admin

      Дано: коллекция account с вложенными объектами коллекции contact.
      Проблема: в коллекции contact есть объекты, которые не содержатся у обьектов account
      Задача: вывести списком contact._id, которых нет у обьектов коллекции account

      Документ коллекции contact

      [
        {
          **"_id": "47d",**
          "_lastUpdatedAt": 1603484561997,
          **"accounts"**: [
            {
              **"accountId": "7eb",**
              "accountNumber": "765",
              "status": 2,
              "isPrimaryOwner": true,
              "alertIds": []
            }
          ],
          "customFieldValues": [],
          "isActive": true,
          "notes": [],
          "primaryAccountId": "7eb",
          "status": 3,
          "type": 1
        }
      ]
      

      Документ коллекции account

      [
        {
          **"_id": "7eb",**
          "_lastUpdatedAt": 1603484561785,
          "accountId": "7eb",
          "accountNumber": "765",
          **"owners"**: [
            {
              **"contactId": "47d"**,
              "type": 1,
              "sourceOf": ""
              },
              "contacts": {
                "phones": [
                  {
                    "phoneId": "016",
                    "type": 4,
                    "isAccountDriven": true
                  },
                  {
                    "phoneId": "337",
                    "type": 4,
                    "isAccountDriven": true
                  }
                ],
                "emails": [
                  {
                    "emailId": "c1a",
                    "type": 3,
                    "isAccountDriven": true
                  }
                ],
                "links": [],
                "addresses": [
                  {
                    "addressId": "9e0",
                    "type": 3,
                    "isAccountDriven": true
                  }
                ],
                "primaryPhoneId": "016",
                "primaryEmailId": "c1a",
                "primaryAddressId": "9e0"
              }
            }
          ],
          "status": 2,
          }
      ]
      

      Составленный запрос в Mongo:

      db.contact.aggregate(
      {
          $lookup:
          {
              from: "account",
              let: { "contactId": "$_id" },
              pipeline: [
                  { $match: { $expr: {$ne:["$contact._id", "$$contactId"] } } },
                  { $group: { _id: "$_id", totalCount: { $sum: 1 } } },
                  { $project: { "_id": 1, "totalCount": 1 } }
                 ],
                as: "contacts"
          }},
          {
              $project: {
                  _id: 1,
                  "totalcontacts" : {$size:"$contacts"}
              } } )
      

      Запрос выдает ошибку:

      com.mongodb.MongoCommandException:
      Command failed with error 16945 (Location16945): 'Exceeded memory limit for $group, but didn't allow external sort. Pass allowDiskUse:true to opt in.' on server хххххх The full response is
      {"operationTime": {"$timestamp": {"t": 1633731680, "i": 8}}, "ok": 0.0, "errmsg": "Exceeded memory limit for $group, but didn't allow external sort. Pass allowDiskUse:true to opt in.", "code": 16945, "codeName": "Location16945", "$clusterTime": {"clusterTime": {"$timestamp": {"t": 1633731680, "i": 8}}, "signature": {"hash": {"$binary": {"base64": "/Sd6PcJ9zyM=", "subType": "00"}}, "keyId": 091949063}}}
      

      Была попытка встроить unwind или allowDiskUse, но не понятно на каком этапе это необходимо делать.

      Admin 1 ответ Последний ответ Ответить Цитировать 0
      • L
        LA @Admin отредактировано

        Пользователь @admin написал в MongoDB: поиск ассиметричных записей:

        [{
        $skip: 100
        }, {
        $limit: 100
        }, {
        $lookup: { ...

        Спасибо большое за помощь!
        Запрос обрабатывает записи группами.

        1 ответ Последний ответ Ответить Цитировать 0
        • L
          LA @Admin отредактировано

          Это сообщение удалено!
          1 ответ Последний ответ Ответить Цитировать 0
          • Admin
            Admin @Admin отредактировано Admin

            Если записей очень много, то Вы можете обрабатывать их группами по 100 записей за раз, например. Для этого можно использовать $skip и $limit.

            [{
                $skip: 100
            }, {
                $limit: 100
            }, {
                $lookup: { ...
            
            L 1 ответ Последний ответ Ответить Цитировать 0
            • Admin
              Admin @LA отредактировано Admin

              Я думаю нужно идти по такому пути:

              1. К коллекции "contact" прицепляем данные из "account" через $lookup.
              2. Ищем те элементы, у которых массив прицепленных данных пустой.
              3. Нужен массив ID? Группируем и убираем лишнее через $project.

              Пример (не проверял):

              [{
                  $lookup: {
                      from: 'account',
                      localField: '_id',
                      foreignField: 'owners.contactId',
                      as: 'accounts'
                  }
              }, {
                  $match: {
                      "accounts": []
                  }
              }, {
                  $group: {
                      _id: null,
                      ids: {
                          '$push': '$_id'
                      }
                  }
              }, {
                  $project: {
                      '_id': 0
                  }
              }]
              
              Admin L 2 ответов Последний ответ Ответить Цитировать 0
              • 1 / 1
              • First post
                Last post
              2020 • Shopker