Как правильно соединить 2 упомянутые коллекции, чтобы правильно выполнить GET / POST - PullRequest
0 голосов
/ 06 февраля 2020

У меня есть 2 коллекции в MongoDB, которые относятся друг к другу. 2 коллекции: - Профили и ссылки на посты OBjectId - Посты со ссылкой на Профили username: {type: Connect.Schema.Types.String}

Моя проблема в том, что в NodeJS API мне нужно выполнить POST для создания нового отправьте URL-адрес примерно так: POST /api/v1/posts/:username, поскольку я публикую для указанного c имя пользователя. POST должен создать новый пост с таким телом, как:

{
   "text": "something"

}

Тогда мне нужно будет увидеть в ответе, если я GET the :username наберу

{
       "username": ":username"    

       "text": "something"

    }

Имя пользователя должно совпадать с именем пользователя в параметрах URL. Поэтому я могу ПОЛУЧИТЬ все сообщения для одного имени пользователя.

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

// Create a new one for the username
    async createNew(req, res) {
        try {
            // Check for an empty body
            if (Object.keys(req.body).length === 0) {
                throw new ErrorHandlers.ErrorHandler(500, "Nothing to create");
            }

            // Req body
            const newPost = req.body;

            // Creating the new post and updating the profile ref
            const addNewPost = await Post.create(newPost);
            addNewPost.username = req.body.username;

            const updateProfile = await Profile.findOneAndUpdate(
                { username: res.username.username },
                { $push: { posts: addNewPost._id } },
                { new: true }
            );

            // Error Check
            if (!addNewPost && !updateProfile) {
                throw new ErrorHandlers.ErrorHandler(
                    500,
                    "Not possible create a new post"
                );
            }

            // Response
            res.status(200).json({
                username: res.username.username,
                newPost: newPost
            });
        } catch (err) {
            res.status(500).json(err);
        }
    }

Мои модели:

// Here defining profile model
// Embedded we have the Experience as []
const { Connect } = require("../db");
const { isEmail } = require("validator");

const postSchema = {
    type: Connect.Schema.Types.ObjectId,
    ref: "Post"
};

const experienceSchema = {
    role: {
        type: String,
        required: true
    },
    company: {
        type: String,
        required: true
    },
    startDate: {
        type: Date,
        required: true
    },
    endDate: {
        type: Date,
        required: false
    },
    description: {
        type: String,
        required: false
    },

    area: {
        type: String,
        required: true
    },
    createdAt: {
        type: Date,
        default: Date.now,
        required: false
    },

    updatedAt: {
        type: Date,
        default: Date.now,
        required: false
    },

    username: {
        type: String,
        required: false
    },
    image: {
        type: String,
        required: false,
        default: "https://via.placeholder.com/150"
    }
};

const profileSchema = {
    firstname: {
        type: String,
        required: true
    },

    surname: {
        type: String,
        required: true
    },

    email: {
        type: String,
        trim: true,
        lowercase: true,
        unique: true,
        required: [true, "Email is required"],
        validate: {
            validator: string => isEmail(string),
            message: "Provided email is invalid"
        }
    },

    bio: {
        type: String,
        required: true
    },

    title: {
        type: String,
        required: true
    },

    area: {
        type: String,
        required: true
    },

    imageUrl: {
        type: String,
        required: false,
        default: "https://via.placeholder.com/150"
    },

    username: {
        type: String,
        required: true,
        unique: true
    },

    experience: [experienceSchema],
    posts: [postSchema],

    createdAt: {
        type: Date,
        default: Date.now,
        required: false
    },

    updatedAt: {
        type: Date,
        default: Date.now,
        required: false
    }
};

const collectionName = "profile";
const profileSchemaModel = Connect.Schema(profileSchema);
const Profile = Connect.model(collectionName, profileSchemaModel);

module.exports = Profile;

const { Connect } = require("../db");

const reactionSchema = {
    likedBy: {
        type: String,
        unique: true,
        sparse: true
    }
};

const postSchema = {
    text: {
        type: String,
        required: true,
        unique: true,
        sparse: false
    },

    username: {
        type: Connect.Schema.Types.String,
        ref: "Profile",
        required: true
    },

    image: {
        type: String,
        default: "https://via.placeholder.com/150",
        required: false
    },
    createdAt: {
        type: Date,
        default: Date.now,
        required: false
    },

    updatedAt: {
        type: Date,
        default: Date.now,
        required: false
    },

    reactions: [reactionSchema],

    comments: {
        type: Connect.Schema.Types.ObjectId,
        ref: "Comment",
        required: false
    }
};

const collectionName = "post";
const postSchemaModel = Connect.Schema(postSchema);
const Post = Connect.model(collectionName, postSchemaModel);

module.exports = Post;

Я хотел бы найти решение для POST одного сообщения для определенного c имени пользователя, указанного в профиле, а затем ПОЛУЧИТЬ все сообщения для одного имени пользователя, как я попробовал ниже без успеха:

async getAllFromProfile(req, res) {
        try {
            const postsFromUsername = await Profile.aggregate([
                {
                    $match: {
                        username: res.username.username
                    }
                },
                {
                    $lookup: {
                        from: "posts    ",
                        localField: "_id",
                        foreignField: "username",
                        as: "posts"
                    }
                },
                {
                    $project: {
                        username: 1,
                        posts: 1,
                        postsCount: {
                            $size: "$posts"
                        },
                        _id: 0
                    }
                }
            ]);

            if (postsFromUsername.length > 0) {
                res.json({ postsFromUsername: postsFromUsername });
            } else {
                throw new ErrorHandlers.ErrorHandler(500, "No data");
            }
        } catch (err) {
            res.status(500).json(err);
        }
    },
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...