Реализация объединений в нескольких коллекциях - PullRequest
2 голосов
/ 24 апреля 2019

Я пытаюсь создать приложение для социальной сети, которое может иметь подключение (подписчики, подписчики), публикации, комментарии, лайки, публикации и т. Д. Это проект MVP, но я все же хотел изучить mongoDB для этого варианта использования.У меня есть некоторые сомнения относительно производительности этого приложения.

У меня есть три коллекции:

  • Сообщения: это место, где должен быть добавлен новый пост.Эта коллекция содержит все детали, связанные с постом.

    Schema: const postSchema = new mongoose.Schema({ user_id: String, title: String, text: String, type: { type: String, enum: ["music", "movie", "tv"] }, mediaUrl: String, thumbnailUrl: String, accessType: { type: Number, enum: [1, 2, 3] }, tags: [String], like_count: Number, comment_count: Number, share_count: Number, insertDate: { type: Date, default: () => { return new Date(); } } });

  • Ленты: эта коллекция просто добавляет метаданные пользователя и сообщения, включая теги.Это я намерен использовать, чтобы получить соответствующий канал для конкретного пользователя.

    Schema: const feedSchema = new mongoose.Schema({ post_id: String, user_id: String, isTag: Boolean, isPublic: Boolean, insertDate: { type: Date, default: () => { return new Date(); } }, modifiedDate: { type: Date, default: () => { return new Date(); } } });

  • Соединения: Эта коллекция предназначена для отношений пользователей.

    Schema: const connectSchema = new mongoose.Schema({ followed_by: String, user_id: String, insertDate: { type: Date, default: () => { return new Date(); } } });

Мой подход состоял в том, чтобы сначала найти сообщения от пользователей из коллекции фидов, на которых я подписан, а затем извлечь сообщения из коллекции постов.Вот мой попытанный запрос:

db.connects.aggregate([
    { $match: { followed_by: "5cbefd61d3b53a4aaa9a2b16" } },
    {
      $lookup: {
        from: "feeds",
        let: { user_id: "$user_id" },
        pipeline: [{ $match: { $expr: { $or: [{ $eq: ["$user_id", "$$user_id"] }, { isPublic: true }] } } }],
        as: "feedData"
      }
    },
    { $unwind: "$feedData" },
    { $replaceRoot: { newRoot: "$feedData" } },
    { $group: { _id: { post_id: { $toObjectId: "$post_id" }, modifiedDate: { $toLong: "$modifiedDate" } } } },
    { $replaceRoot: { newRoot: "$_id" } },
    { $sort: { modifiedDate: -1 } },
    { $skip: 0 },
    { $limit: 10 },
    {
      $lookup: { from: "posts", localField: "post_id", foreignField: "_id", as: "postData" }
    },
    { $unwind: "$postData" },
    { $replaceRoot: { newRoot: "$postData" } },
    { $addFields: { userId: { $toObjectId: "$user_id" } } },
    {
      $lookup: { from: "users", localField: "userId", foreignField: "_id", as: "userData" }
    },
    {
      $project: {
        post_id: "$_id",
        user_id: 1,
        title: 1,
        text: 1,
        typeaccessType: 1,
        mediaUrl: 1,
        thumbnailUrl: 1,
        insertDate: { $toLong: "$insertDate" },
        like_count: 1,
        comment_count: 1,
        share_count: 1,
        user_email: { $arrayElemAt: ["$userData.email", 0] },
        user_profile_pic: { $arrayElemAt: ["$userData.profile_pic", 0] },
        username: { $arrayElemAt: ["$userData.firstname", 0] }
      }
    }
  ]).pretty();

Пожалуйста, поделитесь своим мнением о:

  1. Какой индекс мне следует использовать для повышения производительности?
  2. Есть лилучший способ сделать то же самое в mongoDB.Также, если какая-то часть запроса может быть оптимизирована?
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...