简体   繁体   中英

Mongoose search query with regex not returning expected results with multiple conditions and population

export const searchPost = async (req: any, res: Response) => {
    try {
        const searchQuery = req.params.query;
        const page = req.query.page || 1;
        const limit = req.query.limit || 10;
        const skip = (page - 1) * limit;

        const posts = await Post.find({
            $or:
                [
                    { content: { $regex: searchQuery, $options: 'i' } },
                    { location: { $regex: searchQuery, $options: 'i' } },
                    { 'user.fullName': { $regex: searchQuery, $options: 'i' } },
                    { 'user.username': { $regex: searchQuery, $options: 'i' } },
                    { 'group.name': { $regex: searchQuery, $options: 'i' } }
                ]
        })
            .populate('user')
            .populate('group')
            .skip(skip)
            .limit(limit)
            .sort({ createdAt: -1 });
        res.json(posts);
    } catch (err) {
        console.log(err);
        return res.status(500).json({ message: 'Something went wrong!' });
    }
};

Post Modal

const PostSchema = new Schema(
    {
        content:
            {
                type: String,
                required: true
            },
        location:
            {
                type: String
            },
        image:
            {
                type: String
            },
        user:
            {
                type: Schema.Types.ObjectId,
                ref: 'User',
                required: true
            },
        group:
            {
                type: Schema.Types.ObjectId,
                ref: 'Group'
            },
        comments:
            [
                {
                    type: Schema.Types.ObjectId,
                    ref: 'Comment'
                }
            ],
        likesCount:
            {
                type: Number,
                default: 0
            },
        likesUsers:
            [
                {
                    type: Schema.Types.ObjectId,
                    ref: 'User'
                }
            ]
    },
    { timestamps: true }
);

const Post = mongoose.model('Post', PostSchema);

export default Post;

User Model

const UserSchema = new Schema(
    {
        fullName:
            {
                type: String,
                required: true,
                index: true
            },
        username:
            {
                type: String,
                required: true,
                index: true
            },
        email:
            {
                type: String,
                required: true,
                unique: true
            },
        password:
            {
                type: String,
                required: true
            },
        profileImg:
            {
                type: String,
                default:
                    'https://res.cloudinary.com/dyfm31f1n/image/upload/v1675059905/fit-fiesta/placeholders/blank-profile-picture-gdb207bae8_1280_zymz7e.png'
            },
        coverImg:
            {
                type: String,
                default:
                    'https://res.cloudinary.com/dyfm31f1n/image/upload/v1675059731/fit-fiesta/placeholders/bg_qr4vtm.jpg'
            },
        location:
            {
                type: String
            },
        weight:
            {
                type: Number
            },
        height:
            {
                type: Number
            },
        targetWeight:
            {
                type: Number
            },
        groups:
            [
                {
                    type: Schema.Types.ObjectId,
                    ref: 'Group'
                }
            ],
        events:
            [
                {
                    type: Schema.Types.ObjectId,
                    ref: 'Event'
                }
            ],
        posts:
            [
                {
                    type: Schema.Types.ObjectId,
                    ref: 'Post'
                }
            ],
        connections:
            [
                {
                    type: Schema.Types.ObjectId,
                    ref: 'User'
                }
            ],
        pendingConnections:
            [
                {
                    type: Schema.Types.ObjectId,
                    ref: 'User'
                }
            ]
    },
    { timestamps: true }
);

The Post model has a reference to a User model and a Group model. The method populates these references with their corresponding data using the populate method. The result of the query is sorted in descending order of creation time and sent as a response to the client.

Here in searchPost API its not considering user relation fields such as user.username and user.fullName or group.name while finding with regex

The find , skip , limit , and sort are performed by the mongodb database on the server side. The result is then sent back to mongoose where the populate is performed by submitting additional queries.

In the 'post' document in the database, the 'user' and 'group' fields contains an ObjectId, not an object, so the fields `user.fullName', 'user.username', and 'group.name' don't exist, and therefore don't match.

In order to filter these fields on the database server, you would need to use aggregate with separate $lookup stages to retrieve the user and group documents in order for the server to consider those fields.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM