2

I need to find all documents where first query argument matches then if it can't find more documents that match that query it should apply another query argument.

so for example:

db.users.find({
 $or: [
   { type: typeToSearch },  // First find all users that has type=typeToSearch
   { active: true } // then if it can't find more users with type=typeToSearch then look for active one
]})
.limit(20)

What actually this query does it will find active users first (depending on the order in a collection). What I need is - if I have 18 users that have given type then they should be returned first and then 2 any active.

1 Answer 1

1

That's a cool feature you are looking for! Nothing in Mongoose will help you with this out of the box, and poking around in npm I don't see anything that will help you there either.

For your two queries you have to do something like this:

const  fancyQuery = async  limit => {
    const first = await db.users.find({ type: typeToSearch }).limit(20)
    let second = [];
    if (first.length < limit)
        second = await  db.users.find({ active: true,
        type:{$ne:typeToSearch}} })
       .limit(20-first.length)
    return [...first, ...second]
}

The only other path I can think of using the query api, is to fetch 40 items and then to filter the results with javascript. I think you'd need to change your query a little to prevent the active = true part of the query from also refetching all the same documents as the type query:

db.users.find({
    $or: [
        { type: typeToSearch },
        { active: true,
          type: {$ne: typeToSearch}
        }
    ]})
    .limit(40) 

You'd filter the results first by type and then by not type and active up to 20 items.

You might also be able to use an aggregation pipeline to accomplish this, but I don't have an answer like that at my finger-tips.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks! I wonder if it would be possible to do it one query but adding some sorting condition.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.