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 yourfind
query. - Then use
$unwind
to deconstruct the array and look in each value. $match
to find a value whichpincode
andisLive
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