skip to Main Content

Simply, I am working on a project and I faced a case and want to know if I am implementing it correctly.

I expect the client to send an array of IDs, and I need to check if each value in the array exists or not in the database. If any value does not exist, I will send a response with an error. Otherwise, I will proceed with the next actions.

I have implemented the idea in the following way:

let result = null;

for (let i = 0; i < listIds.length; i++) {
    const existCheck = await branchModel.exists({ _id: listIds[i] }) != null ? true : false;

    if (existCheck == false) {
        result = false;
    }
}

if (result != false) {
    result = true;
}

return result;
}

However, I think this approach may impact performance if the array is very long, and I am not sure if calling the database multiple times in the same API is healthy and not expensive.

Is there a method in Mongoose to achieve the same idea?

2

Answers


  1. Yes that will impact performance because as per the docs:

    Under the hood, MyModel.exists({ answer: 42 }) is equivalent to MyModel.findOne({ answer: 42 }).select({ _id: 1 }).lean()

    So if listIds is a long array then you are doing a findOne once per each item in the array so that is one database call per array item.

    I have had to do something similar like this in the past and if you are only concerned with knowing that at least one _id is not there and not necessarily worried about which one then you can just get all documents with an $in and then comparing the length of the listIds with the length of the documents. Given that _id is unique, if they don’t match then at least one is not there.

    const docs = await branchModel.find({ _id: { $in: listIds } } );
    return docs.length === listIds.length;
    

    Or with using mongoose Query Builders:

    const docs = await branchModel.find().where('_id').in(listIds);
    return docs.length === listIds.length;
    
    Login or Signup to reply.
  2. Use countDocuments in Mongoose and filter by the _ids in listIds.

    If the count of docs is not the same as the length of the list, then one or more objectIDs were missing. Add a step to make listIds unique. Otherwise, ["aaa", "aaa", "aaa"] would give an error since you’d get back only one document for one "aaa", ie count=1 even though the input was 3.

    var listIds = ['a', 1, 'a', 2, '1'];
    let uniqueIds = [...new Set(listIds)];
    
    const existsCount = await branchModel.countDocuments({ _id: { $in: uniqueIds } });
    return existsCount === uniqueIds.length;
    

    And if listIds is are, convert them to ObjectIDs before doing countDocuments. Edit: This conversion is not needed since mongoose will do that automatically.

    Note: It’s probably be better to use find + length as per jQueeny’s answer since it would use the index on _id. But for countDocs:

    If you call countDocuments({}) , MongoDB will always execute a full collection scan and not use any indexes.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search