Home > front end >  How To Query nested mongoDB with $or query in nested field of arrays in NodeJs
How To Query nested mongoDB with $or query in nested field of arrays in NodeJs

Time:10-20

I am trying to query mongoDB collection to fetch and match a specific date range and a specific array of ids, such as brachIds, or servicesIds.

I want the query if it finds this result to return it, so that i can validate if a request already exists in that collection by a specific user.

But whenever I pass array values to the $or [{}] segment of the query, no result comes back when i use $all

what am I doing wrong?

Below code that is working and retrieving the document:

 db.collection("requests")
                    .find({'filter.dateRange.from': {$eq: moment(from, "YYYY-MM-DD").startOf('day').format("YYYY-MM-DD[T]HH:mm:ss.SSS[Z]")},
                        'filter.dateRange.to': {$eq: moment(to, "YYYY-MM-DD").startOf('day').format("YYYY-MM-DD[T]HH:mm:ss.SSS[Z]")},
                     
                        $or: [{'filter.branchesIds': {$eq: branchesIds }},{'filter.groupOfBranchesIds': { $eq: servicesIds }},{'filter.servicesIds': {$eq: groupOfBranchesIds }}]})
                    .toArray()
                    .then(result => {

                           
                            if (result.length) {

                                resolve(result)

                            } else {
                         
                                resolve(result)

                            }
                        }).catch(error => {
                            console.log(error);
                        })

Below code using $all that makes the query not return any document:

            let _branchIds = branchesIds || [];
            let _servicesIds = servicesIds || [];
            let _groupOfBranchesIds = groupOfBranchesIds || [];

 db.collection("requests")
                    .find({'filter.dateRange.from': {$eq: moment(from, "YYYY-MM-DD").startOf('day').format("YYYY-MM-DD[T]HH:mm:ss.SSS[Z]")},
                        'filter.dateRange.to': {$eq: moment(to, "YYYY-MM-DD").startOf('day').format("YYYY-MM-DD[T]HH:mm:ss.SSS[Z]")},
                    
                        $or: [{'filter.branchesIds': {$all: _branchIds }},{'filter.groupOfBranchesIds': { $all: _servicesIds }},{'filter.servicesIds': {$all: _groupOfBranchesIds }}]})
                    .toArray()
                    .then(result => {

                          
                            if (result.length) {

         
                                resolve(result)

                            } else {
                                
                    
                                resolve(result)

                            }
                        }).catch(error => {
                            console.log(error);
                        })

CodePudding user response:

First you must make sure that your parameters are arrays, so you must convert them as follows:

    if (!branchesIds ) {
    branchesIds = [branchesIds];
}

if (!servicesIds ) {
    servicesIds = [servicesIds];
}

if (!groupOfBranchesIds ) {
    groupOfBranchesIds = [groupOfBranchesIds];
}

Then your query should use the $in:

find({'filter.dateRange.from': {$eq: moment(from, "YYYY-MM-DD").startOf('day').format("YYYY-MM-DD[T]HH:mm:ss.SSS[Z]")},
    'filter.dateRange.to': {$eq: moment(to, "YYYY-MM-DD").startOf('day').format("YYYY-MM-DD[T]HH:mm:ss.SSS[Z]")},
    $or: [{'filter.branchesIds': { $in: branchesIds }},{'filter.groupOfBranchesIds': { $in: groupOfBranchesIds }},{'filter.servicesIds': { $in: servicesIds }}]})
.sort({_created_at: -1})
.toArray()

This should now work. Hope this helps!

CodePudding user response:

you use $eq instead of $in, use $in when you want to do operations on arrays

$or: [{'filter.branchesIds': {$in: branchesIds }},{'filter.groupOfBranchesIds': { $in: servicesIds }},{'filter.servicesIds': {$in: groupOfBranchesIds }}]})
  • Related