Search code examples
node.jsmongodbmongoosemongodb-querymongoose-schema

Why $or is not working properly in mongoose with regular expression


I'm trying to fetch documents which contain whatever I pass in url for filter which must present in title field or in tasks array of those documents:

example: localhost:4000/search?filter=Morning. here I'm looking for documents which contain Morning in their title or in their tasks.

But when I'm hitting the Api it is returning me all the documents.

{
    "success": true,
    "message": "Successfully fetched todos",
    "filteredArray": [
        {
            "_id": "6386e34e2c65763cf25008f3",
            "toDoTitle": {
                "title": "Morning routines",
                "_id": "6386e34e2c65763cf25008f4",
                "createdAt": "2022-11-30T04:59:58.940Z",
                "updatedAt": "2022-11-30T04:59:58.940Z"
            },
            "toDoTasks": {
                "tasks": [
                    "code",
                    "sleep",
                    "code",
                    "eat",
                    "code"
                ],
                "_id": "6386e34e2c65763cf25008f5",
                "createdAt": "2022-11-30T04:59:58.941Z",
                "updatedAt": "2022-11-30T04:59:58.941Z"
            },
            "createdAt": "2022-11-30T04:59:58.941Z",
            "updatedAt": "2022-11-30T04:59:58.941Z",
            "__v": 0
        },
        {
            "_id": "6386e3552c65763cf25008f7",
            "toDoTitle": {
                "title": "Morning",
                "_id": "6386e3552c65763cf25008f8",
                "createdAt": "2022-11-30T05:00:05.813Z",
                "updatedAt": "2022-11-30T05:00:05.813Z"
            },
            "toDoTasks": {
                "tasks": [
                    "code",
                    "sleep",
                    "code",
                    "eat",
                    "code"
                ],
                "_id": "6386e3552c65763cf25008f9",
                "createdAt": "2022-11-30T05:00:05.813Z",
                "updatedAt": "2022-11-30T05:00:05.813Z"
            },
            "createdAt": "2022-11-30T05:00:05.813Z",
            "updatedAt": "2022-11-30T05:00:05.813Z",
            "__v": 0
        },
        {
            "_id": "6386e35f2c65763cf25008fb",
            "toDoTitle": {
                "title": "evening",
                "_id": "6386e35f2c65763cf25008fc",
                "createdAt": "2022-11-30T05:00:15.809Z",
                "updatedAt": "2022-11-30T05:00:15.809Z"
            },
            "toDoTasks": {
                "tasks": [
                    "code",
                    "sleep",
                    "code",
                    "eat",
                    "code"
                ],
                "_id": "6386e35f2c65763cf25008fd",
                "createdAt": "2022-11-30T05:00:15.809Z",
                "updatedAt": "2022-11-30T05:00:15.809Z"
            },
            "createdAt": "2022-11-30T05:00:15.810Z",
            "updatedAt": "2022-11-30T05:00:15.810Z",
            "__v": 0
        },
        {
            "_id": "6386e3672c65763cf25008ff",
            "toDoTitle": {
                "title": "evening",
                "_id": "6386e3672c65763cf2500900",
                "createdAt": "2022-11-30T05:00:23.977Z",
                "updatedAt": "2022-11-30T05:00:23.977Z"
            },
            "toDoTasks": {
                "tasks": [
                    "code"
                ],
                "_id": "6386e3672c65763cf2500901",
                "createdAt": "2022-11-30T05:00:23.977Z",
                "updatedAt": "2022-11-30T05:00:23.977Z"
            },
            "createdAt": "2022-11-30T05:00:23.977Z",
            "updatedAt": "2022-11-30T05:00:23.977Z",
            "__v": 0
        },
        {
            "_id": "6386e3712c65763cf2500903",
            "toDoTitle": {
                "title": "night",
                "_id": "6386e3712c65763cf2500904",
                "createdAt": "2022-11-30T05:00:33.286Z",
                "updatedAt": "2022-11-30T05:00:33.286Z"
            },
            "toDoTasks": {
                "tasks": [
                    "code"
                ],
                "_id": "6386e3712c65763cf2500905",
                "createdAt": "2022-11-30T05:00:33.286Z",
                "updatedAt": "2022-11-30T05:00:33.286Z"
            },
            "createdAt": "2022-11-30T05:00:33.287Z",
            "updatedAt": "2022-11-30T05:00:33.287Z",
            "__v": 0
        }
    ]
}

This is my model

const mongoose = require("mongoose");
const schema = mongoose.Schema;

const title = new schema(
    {
       title:{ 
        type: String,
        trim: true
        }

    },
    {
        timestamps: true 
    }

    );

const task = new schema(
    {
    tasks:[{ type: String,trim: true}]
    },
    {
    timestamps: true 
    }
    )   

const toDoSchema = new schema({
    toDoTitle : title,
    toDoTasks: task

    },
    {
    timestamps: true 
    });

const toDoModel = mongoose.model("toDo", toDoSchema);
module.exports = toDoModel;

this is my controller for filtering:

//importing model
const toDoModel = require('../models/ToDoModel');

//importing utils function
const toDosPerPage = require("../utlis/ToDosPerPage")

const searchController = async (req,res)=>{

    try{
        const {filter} = req.query
        if(!filter) throw new Error("Please provide Something in filter to search");
        const filteredArray = await toDoModel.find({
            $or:[{title:new RegExp(filter,'i')},{tasks: new RegExp(filter,'i')}]
        });

        
        
        res.status(200).json({
            success: true,
            message: "Successfully fetched todos",
            filteredArray

        });

        }
        catch(err){
            res.status(401).json({
                success: false,
                message: "Some error occuried",
                error: err.message
            })
            console.log(err.message);
        } 
    }
    module.exports = searchController;

I want it to return only those documents which contain morning in their title or in their tasks fields.


Solution

  • to find in embeded document use dot .

    const filteredArray = await toDoModel.find({
       $or:[
            {'toDoTitle.title':new RegExp(filter,'i')},
            {'toDoTasks.tasks':new RegExp(filter,'i')}
       ]
    });