Home > Net >  Find all documents in one model using property of another model in Mongoose
Find all documents in one model using property of another model in Mongoose

Time:04-21

I have two models named post and user. The Post Model is as defined below:

const postSchema = new mongoose.Schema({
    _id: {
        type: mongoose.Types.ObjectId,
        auto: true,
    },
    userId: {
        type: mongoose.Types.ObjectId,
        required: true
    },
    header: {
        type: String,
        max: 1024,
        required: true,
    },
    body: {
        type: String,
    },
    tags: {
        type: Array,
        default: []
    }
});

The user model is as defined below:

const userSchema = new mongoose.Schema({
    _id: {
        type: mongoose.Types.ObjectId,
        auto: true,
    },
    username: {
        type: String,
        required: true,
        max: 255,
    },
    email: {
        type: String,
        required: true,
        max: 255,
    },
    password: {
        type: String,
        required: true,
        min: 6,
        max: 1024,
    },
    role: {
        type: String,
        required: true,
        max: 255,
    },
    tags: {
        type: Array,
        default: []
    }
});

I need to get all the posts that have tags similar to User Tags. That means if User Tags has tag-1, and tag-2 I need all the posts which have tag-1 and tag-2 or just tag-1 or tag-2. At present, I am doing as below.

    tagsInfo = [];
    await User.findById(req.body.userId).then((userInfo, err) => {
        for (let i = 0; i < userInfo.tags.length; i  ) {
            tagsInfo.push(userInfo.tags[i]);
        }
    });
    postsArray = [];
    for (let i = 0; i < tagsInfo.length; i  ) {
        await Post.find({ tags: tagsInfo[i] }).then((posts, err) => {
            postsArray = [...postsArray, posts];
        });
    }

I was just wondering if there is a better way to get all the posts that have user tags.

CodePudding user response:

Not sure why are you pushing the user tags to tagsInfo array. but can you do

let user = await User.findById(req.body.userId);

You can use $in operator in order to avoid the second loop. You can put if check if needed (I'm assuming findById returns value).

let Post = await Post.find({
    tags: {
        "$in": user.tags
    }
});

If you are doing async/await don't use then/catch syntax. use one not both

  • Related