Sindbad~EG File Manager

Current Path : /home/infinitibizsol/.trash/controllers.8/common/
Upload File :
Current File : /home/infinitibizsol/.trash/controllers.8/common/globalSearch.js

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