Home > Back-end >  How can i optimize below query in Mongoose?
How can i optimize below query in Mongoose?

Time:09-27

Basically, I want to fetch data from collection where pincode field(inside Location array) is matched by req.body I'm getting my desired output but I'm not sure if it's a optimized way or not (look in Mongoose query part)

Here's my Json:

{
    "_id" : ObjectId("6115b2cc1681596a10072f97"),
    "vendorStatus" : "Active",
    "name" : "harshit singh bhutani",
    "email" : "[email protected]",
    "vId" : 12121,
    "contact" : 121212,
    "cities" : "dell",
    "isMidnight" : "NA",
    "location" : [ 
        {
            "delivery" : 1266,
            "dc" : "High",
            "midnight" : "Active",
            "isLive" : "NA",
            "_id" : ObjectId("612433c27292d11154bc4d4d"),
            "pincode" : 123100,
            "city" : "dek"
        }, 
        {
            "delivery" : 23,
            "dc" : "High",
            "midnight" : "Active",
            "isLive" : "NA",
            "_id" : ObjectId("612441473cb5766a2457d6db"),
            "pincode" : 1212,
            "city" : "dd"
        }
    ],
    
    "createdAt" : ISODate("2021-08-12T23:46:20.407Z"),
    "updatedAt" : ISODate("2021-09-03T10:51:34.756Z"),
    "__v" : 73
}

Here's my query in Mongoose:

  const { pin } = req.body;
  const vendor = await Vendor.find({ vendorStatus: "Active" });

  const pincode = vendor.map((item) => {
    return item.location.find((i) => {
      if (i.pincode === Number(pin) && i.isLive === "Active") {
        return i;
      }
    });
  });

  const pincodefound = pincode.filter(Boolean);
  if (pincodefound.length === 0) {
    res.status(404);
    throw Error("Product is not Deliverable at this Pincode");
  } else {
    return res.json({
      pincodefound,
    });
  }

First I use map to iterate then I used find to grab the matched pincode after that I'm getting array with output and null value so I use filter to get only pincode though I get my desired output BUT still I'm not sure weather its a optimized approach or not.

CodePudding user response:

If I understood correctly your JS code you want to get only the value into the location array which match the condition.

In this case is a better way to do everything in a query. You can use an aggregation pipeline.

This query:

  • First match by vendorStatus: "Active like your find query.
  • Then use $unwind to deconstruct the array and look in each value.
  • $match to find a value which pincode and isLive are desired values.
  • And last stage is $project to show only values you want, in this case, the location values.
const pincode = await Vendor.aggregate([
  {
    "$match": {
      "vendorStatus": "Active"
    }
  },
  {
    "$unwind": "$location"
  },
  {
    "$match": {
      "location.pincode": pin,
      "location.isLive": "Active"
    }
  },
  {
    "$project": {
      "delivery": "$location.delivery",
      "dc": "$location.dc",
      "midnight": "$location.midnight",
      "isLive": "$location.isLive",
      "_id": "$location._id",
      "pincode": "$location.pincode",
      "city": "$location.city"
    }
  }
]);

Example here

  • Related