Sindbad~EG File Manager
import catchAsync from "../../utils/catchAsync";
import db from "../../model/index";
import { successResponse } from "../../utils/responseFormat";
import mongoose from "mongoose";
const universalSearch = catchAsync(async (req, res, next) => {
const models = ["User", "Policy", "Contact"];
const searchQuery = req.query.q;
if (!searchQuery) {
return next(new Error("Search query is required."));
}
const searchPromises = models.map((model) => searchModel(model, searchQuery));
let searchResults = await Promise.all(searchPromises);
// Filter out results with empty data
searchResults = searchResults.filter((result) => result.data.length > 0);
// Flatten the data so that each type has a single object instead of an array
const formattedResults = searchResults
.map((result) => {
if (
result.type === "User" ||
result.type === "Policy" ||
result.type === "Contact"
) {
return result.data.map((item) => ({
type: result.type,
data: item,
}));
}
return result;
})
.flat();
return successResponse(res, formattedResults);
});
const searchModel = async (modelName, searchQuery) => {
let query = db[modelName]
.find(
{ $text: { $search: searchQuery } },
{ score: { $meta: "textScore" } }
)
.sort({ score: { $meta: "textScore" }, createdOn: -1 })
.lean();
const data = await query.exec();
if (modelName === "Contact" || modelName === "User") {
return {
type: modelName,
data: await enrichContactsWithPolicies(data),
};
}
return { type: modelName, data };
};
const enrichContactsWithPolicies = async (contacts) => {
return Promise.all(
contacts.map(async (contact) => {
contact.policies = await db.Policy.find({
contact_id: contact._id,
})
.populate("user_id", "_id first_name")
.populate("contact_id", "_id first_name")
.lean();
let { phone_no, email } = await getPrimaryPhone(contact._id);
contact.primary_phone = phone_no;
contact.primary_email = email;
contact.primary_address = await getPrimaryAddress(contact._id);
return contact;
})
);
};
const getPrimaryPhone = async (docId) => {
const filteredData = await db.BasicContactInfo.aggregate([
{
$match: {
$or: [
{
contact_id: mongoose.Types.ObjectId(docId),
},
{
user_id: mongoose.Types.ObjectId(docId),
},
],
},
},
{
$project: {
phone_numbers: {
$cond: {
if: { $isArray: "$phone_numbers" },
then: {
$filter: {
input: "$phone_numbers",
as: "phone",
cond: { $eq: ["$$phone.is_primary", true] },
},
},
else: [],
},
},
emails: {
$cond: {
if: { $isArray: "$emails" },
then: {
$filter: {
input: "$emails",
as: "email",
cond: { $eq: ["$$email.is_primary", true] },
},
},
else: [],
},
},
},
},
{
$unwind: {
path: "$phone_numbers",
},
},
{
$unwind: {
path: "$emails",
},
},
{
$project: {
phone_no: "$phone_numbers.phone_no",
email: "$emails.email_address",
},
},
]);
return {
phone_no:
filteredData.length > 0 && filteredData[0].phone_no
? filteredData[0].phone_no
: null,
email:
filteredData.length > 0 && filteredData[0].email
? filteredData[0].email
: null,
};
};
const getPrimaryAddress = async (docId) => {
const filteredData = await db.Address.findOne(
{
$and: [
{
$or: [{ user_id: docId }, { contact_id: docId }],
},
{ primary_address: true },
],
},
["street", "apt_or_suit", "city", "province", "country"]
);
return filteredData;
};
export default { universalSearch };
Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists