Hi i want to get data nearby location for that I am providing coordinates so its giving right data but I want all data in sorting order by coordinates like I have searched for vadodara then it should all data in vadodara then nearby vadodara like ahemdabad then gujrat state then madhya pradesh, maharathan then India then nepal like so
public list = async ( input: HomePageListingDto, ): Promise<ServiceResponse> => { try { const { facilityType, conditionTreated, specialized, medicationTherapy, treatmentApproaches, preTreatment, testing, smokingPolicy, allowableStay, verifiedBadge, featured, searchBar, page, perPage, genderSpecific, gender, insurance, offersScholarships, coordinates, } = input;
const coordinatesProvided = !isNil(coordinates);
const query = coordinatesProvided
? this.createGeoQueryOld(coordinates)
: null;
const filter: any = {
facilityType,
deletedAt: { $exists: false },
$or: [{ isSubscribed: true }, { isClaimRequest: true }],
};
if (coordinatesProvided) {
filter["coordinates.coordinates"] = query;
}
if (conditionTreated?.length) {
this.mapOptionsToFilter(
conditionTreated,
"conditionTreated",
filter,
);
}
if (specialized?.length) {
this.mapOptionsToFilter(specialized, "specialization", filter);
}
if (medicationTherapy?.length) {
this.mapOptionsToFilter(
medicationTherapy,
"medicationTherapy",
filter,
);
}
if (treatmentApproaches?.length) {
this.mapOptionsToFilter(
treatmentApproaches,
"treatmentApproaches",
filter,
);
}
if (preTreatment?.length) {
this.mapOptionsToFilter(preTreatment, "preTreatment", filter);
}
if (testing?.length) {
this.mapOptionsToFilter(testing, "testing", filter);
}
if (smokingPolicy?.length) {
this.mapOptionsToFilter(smokingPolicy, "smokingPolicy", filter);
}
const from = Number(allowableStay?.from);
const to = Number(allowableStay?.to);
if (!isNaN(from) && !isNaN(to) && to >= from) {
filter["allowableStay.from"] = { $lte: from };
filter["allowableStay.to"] = { $gte: to };
} else if (!isNaN(from) && !isNaN(to)) {
filter["allowableStay.from"] = { $lte: 0 };
filter["allowableStay.to"] = { $gte: 0 };
}
if (verifiedBadge) {
filter.isVerified = true;
}
if (genderSpecific) {
filter.genderSpecific = genderSpecific;
}
if (genderSpecific && gender) {
filter.gender = gender;
}
if (insurance?.length) {
this.mapOptionsToFilter(insurance, "insurance", filter);
}
if (offersScholarships) {
filter.offersScholarships = offersScholarships;
}
if (searchBar) {
const searchBarRegex = { $regex: searchBar, $options: "i" };
filter.$or = [
{ city: searchBarRegex },
{ state: searchBarRegex },
{ name: searchBarRegex },
{ "geocodingResult.cityName": searchBarRegex },
{ "geocodingResult.stateLong": searchBarRegex },
];
}
let facilityList = [];
let totalCount = 0;
const skip = !isNil(page) ? (page - 1) * perPage : 0;
const limit = perPage;
if (featured) {
// Fetch all relevant facilities
facilityList = await this.facility.find(filter).populate({
path: "subscriptionDetail",
select:
"price subscriptionType interval status subscriptionId stripeCustomerId currency invoiceId currentPeriodEnd -_id",
});
//Filter out non-pro facilities
facilityList = facilityList.filter(
facility =>
facility?.subscriptionDetail?.subscriptionType ===
"pro" &&
(facility?.isSubscribed === true ||
facility?.isClaimRequest === true),
);
// Sort the filtered list
facilityList.sort((a, b) => {
return (
b.isPPCSubscribed - a.isPPCSubscribed ||
b.isSubscribed - a.isSubscribed ||
b.subscriptionDetail?.subscriptionType?.localeCompare(
a.subscriptionDetail?.subscriptionType,
) ||
b.isVerified - a.isVerified ||
b.rating - a.rating ||
a._id - b._id
);
});
// Calculate total count after filtering
totalCount = facilityList.length;
// Apply pagination
facilityList = facilityList.slice(skip, skip + limit);
} else {
// Get total count with filter
// Fetch facilities with pagination
facilityList = await this.facility
.find(filter)
.populate({
path: "subscriptionDetail",
select:
"price subscriptionType interval status subscriptionId stripeCustomerId currency invoiceId currentPeriodEnd -_id",
})
.sort({
isPPCSubscribed: -1,
isSubscribed: -1,
// Note: Sorting directly on populated fields is not possible,
// so sorting on "subscriptionDetail.subscriptionType" is omitted here
isVerified: -1,
rating: -1,
_id: 1,
});
facilityList = facilityList.filter(
facility =>
facility?.isSubscribed === true ||
facility?.isClaimRequest === true,
);
// Sort in application code if necessary
facilityList.sort((a, b) => {
return (
b.isPPCSubscribed - a.isPPCSubscribed ||
b.isSubscribed - a.isSubscribed ||
b.subscriptionDetail?.subscriptionType?.localeCompare(
a.subscriptionDetail?.subscriptionType,
) ||
b.isVerified - a.isVerified ||
b.rating - a.rating ||
a._id - b._id
);
});
totalCount = facilityList.length;
// Apply pagination
facilityList = facilityList.slice(skip, skip + limit);
}
if (!isNil(coordinates)) {
const allData = await this.getbyWithoutCoordinates(
featured,
filter,
);
facilityList = [...facilityList, ...allData];
facilityList = facilityList.filter(
(item, index) =>
facilityList.findIndex(
facility => facility.id === item.id,
) === index,
);
totalCount = facilityList.length;
facilityList = facilityList.slice(skip, skip + limit);
}
const transformed = await Promise.all(
facilityList.map(d => {
this.ctrImpressionService.createCTRImpression({
facilityId: d._id,
typeOfImpression: ["facility"],
});
return new EFacilityBuilder(d, {
mediaService: this.mediaService,
}).getResult();
}),
);
return {
error: null,
data: {
total: totalCount,
facilities: transformed,
},
};
} catch (error) {
console.error("Error in listing facilities:", error);
return { error: facilityTypeIsRequired, data: null };
}
};
public getbyWithoutCoordinates = async (featured: any, filter: any) => {
delete filter["coordinates.coordinates"];
let facilityList = [];
if (featured) {
// Fetch all relevant facilities
facilityList = await this.facility.find(filter).populate({
path: "subscriptionDetail",
select:
"price subscriptionType interval status subscriptionId stripeCustomerId currency invoiceId currentPeriodEnd -_id",
});
//Filter out non-pro facilities
facilityList = facilityList.filter(
facility =>
facility?.subscriptionDetail?.subscriptionType === "pro" &&
(facility?.isSubscribed === true ||
facility?.isClaimRequest === true),
);
// Sort the filtered list
facilityList.sort((a, b) => {
return (
b.isPPCSubscribed - a.isPPCSubscribed ||
b.isSubscribed - a.isSubscribed ||
b.subscriptionDetail?.subscriptionType?.localeCompare(
a.subscriptionDetail?.subscriptionType,
) ||
b.isVerified - a.isVerified ||
b.rating - a.rating ||
a._id - b._id
);
});
} else {
// Get total count with filter
// Fetch facilities with pagination
facilityList = await this.facility
.find(filter)
.populate({
path: "subscriptionDetail",
select:
"price subscriptionType interval status subscriptionId stripeCustomerId currency invoiceId currentPeriodEnd -_id",
})
.sort({
isPPCSubscribed: -1,
isSubscribed: -1,
// Note: Sorting directly on populated fields is not possible,
// so sorting on "subscriptionDetail.subscriptionType" is omitted here
isVerified: -1,
rating: -1,
_id: 1,
});
facilityList = facilityList.filter(
facility =>
facility?.isSubscribed === true ||
facility?.isClaimRequest === true,
);
// Sort in application code if necessary
facilityList.sort((a, b) => {
return (
b.isPPCSubscribed - a.isPPCSubscribed ||
b.isSubscribed - a.isSubscribed ||
b.subscriptionDetail?.subscriptionType?.localeCompare(
a.subscriptionDetail?.subscriptionType,
) ||
b.isVerified - a.isVerified ||
b.rating - a.rating ||
a._id - b._id
);
});
}
return facilityList;
};
public createGeoQueryOld = ({
lat,
lng,
}: {
lat: number;
lng: number;
}): any => {
const maxDistanceInMeters = 100000; //?100km which means 60 miles
return {
$near: {
$geometry: {
type: "Point",
coordinates: [lng, lat],
},
$maxDistance: maxDistanceInMeters,
},
};
};