совокупный вложенный массив объектов с помощью мангуста - PullRequest
0 голосов
/ 24 января 2020

У меня есть следующая модель, и я хочу запросить указанного пользователя c в поле _id и заполнить массив inbox.messages необходимыми данными, которые соответствуют соответствующему полю _id в модели пользователей, и, что более важно, я также хочу группируйте каждое сообщение по полю 'from' и возвращайте этот результат

const UserSchema = new Schema({
   username: {
        type: String,
        required: true,
    },

    blockedUsers: {
        users: [
            {
                userId: {type: Schema.Types.ObjectId, ref: 'User', required: true },
            }
        ]
    },
    favorites: {
        users: [
            {
                userId: {type: Schema.Types.ObjectId, ref: 'User', required: true },
            }
        ]
    },
    profileViews: {
        views: [
            {
                userId: {type: Schema.Types.ObjectId, ref: 'User', required: true },
                date: {type: Date}
            }
        ]
    },
    inbox: {
        messages: [
            {
                messageId: {type: Schema.Types.ObjectId},
                from: {type: Schema.Types.ObjectId, ref: 'User', required: true },
                content: {type: String, required: true},
                date: {type: Date}
            }
        ]
    },
    images: {
        "imagePaths": [
            {   
                imageId: {type: Schema.Types.ObjectId},
                path: { type: String, required: true},
                date: {type: Date}
            }
        ],
    }
})

того, что у меня есть до сих пор

  let incomingId = '5e29fd75fdfd5320d0e42bc4';
  let myUser = await User.aggregate([
           { $match: {"_id": mongoose.Types.ObjectId(incomingId) }},
           { $lookup: { }}
         ])

Не совсем точно, что поместить в поле $ lookup или, если это даже правильно.

В качестве примера я хотел бы, чтобы документы выглядели так:

[
  {
    "from": "5e240f7480a24e07d832c7bd",
    "username":"hable0",
    "images": {
      imagePaths: [
         'images/2020-09-24-Z_34234342_12.jpg'
      ],
     },
    "inbox": {
      "messages": [
        {
          "messageId": "5e2a110a21c64d63f451e39e",
          "content": "Message content",
          "date": "2020-01-23T21:32:58.126Z"
        },
        {
          "messageId": "5e2a111321c64d63f451e3a0",
          "content": "Message content",
          "date": "2020-01-23T21:33:07.378Z"
        },
        {
          "messageId": "5e2a112321c64d63f451e3a2",
          "content": "Message content",
          "date": "2020-01-23T21:33:23.036Z"
        }
      ]
    }
  }
]

1 Ответ

0 голосов
/ 24 января 2020

Вы можете попробовать следующий конвейер с aggregate().

  • Найти документ, который соответствует идентификатору
  • Размотка inbox.messages
  • Группировка по from field
  • Выполните $lookup, чтобы получить другой документ
  • Выполните $unwind, чтобы уничтожить массив
  • Укажите поля, которые будут включены в вывод
let myUser = await User.aggregate([
  {
    $match: { "_id": mongoose.Types.ObjectId(incomingId) }
  },
  {
    $unwind: "$inbox.messages"
  },
  {
    $group: {
      _id: { from: "$inbox.messages.from" },
      messages: {
        $push: {
          messageId: "$inbox.messages.messageId"
          // Add more info of the message here as needed
        }
      }
    },
  },
  {
    $lookup: {
      from: "User",
      localField: "_id.from",
      foreignField: "_id",
      as: "extraUserInfo"
    }
  },
  {
    $unwind: "$extraUserInfo"
  },
  {
    $project: {
      _id: 0,
      from: "$_id.from",
      inbox: { messages: "$messages" },
      username: "$extraUserInfo.username",
      images: "$extraUserInfo.images"
    }
  }
]);

Пример вывода:

{
  "from": "user1",
  "inbox": {
    "messages": [{
      "messageId": "message1-from-user1"
    }]
  },
  "username": "user1-username",
  "images": {
    "imagePaths": ["image-path-user1"]
  }
} {
  "from": "user2",
  "inbox": {
    "messages": [{
      "messageId": "message1-from-user2"
    }, {
      "messageId": "message2-from-user2"
    }, {
      "messageId": "message3-from-user2"
    }]
  },
  "username": "user2-username",
  "images": {
    "imagePaths": ["image-path-user2"]
  }
} {
  "from": "user3",
  "inbox": {
    "messages": [{
      "messageId": "message1-from-user3"
    }, {
      "messageId": "message2-from-user3"
    }]
  },
  "username": "user3-username",
  "images": {
    "imagePaths": ["image-path-user3"]
  }
}

Надеюсь, что это ответит на часть вашего вопроса. Хотя мне не очень понятно, как вы хотели бы заполнить массив messages пользовательской информацией, которая отправляла сообщения. Но вы можете выполнить $lookup() с конвейером после операции $group(), чтобы прикрепить дополнительную информацию от отправителя к результату.

Подробнее о $ unwind , $ group , $ project и $ lookup .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...