Home > Mobile >  how to refactoring $expr, $regexMatch filter for easier reading React/MongoDB?
how to refactoring $expr, $regexMatch filter for easier reading React/MongoDB?

Time:09-22

I would like to explain my problem of the day.

Currently I perform a filter on an input which allows me to search the last name and first name it works really well

I have deleted a lot of things for a simpler reading of the code if there is a need to bring other element do not hesitate to ask

const {
    data: packUsersData,
       } = useQuery(
    [
        "pack",
        id,
        "users",
        ...(currentOperatorsIds.length ? currentOperatorsIds : []),
        value,
    ],
    async () => {
        const getExpr = () => ({
            $expr: {
                $or: [
                    {
                        $regexMatch: {
                            input: {
                                $concat: ["$firstName", " ", "$lastName"],
                            },
                            regex: value,
                            options: "i",
                        },
                    },
                    {
                        $regexMatch: {
                            input: {
                                $concat: ["$lastName", " ", "$firstName"],
                            },
                            regex: value,
                            options: "i",
                        },
                    },
                ],
            },
        });

        let res = await usersApi.getrs({
            pagination: false,
            query: {
                "roles.name": "operator",
                _id: { $nin: currentOperatorsIds },
                deletedAt: null,
                $or: value
                    ? [
                          {
                              entities: [],
                              ...getExpr(),
                          },
                          {
                              entities: { $in: id },
                              ...getExpr(),
                          },
                      ]
                    : [
                          {
                              entities: [],
                          },
                          {
                              entities: { $in: id },
                          },
                      ],
            },
            populate: "entity",
            sort: ["lastName", "firstName"],
        });
    {
        refetchOnMount: true,
    }
);

and so i find the read a bit too long have any idea how i could shorten all this?

thx for help.

CodePudding user response:

  1. You can reduce entities field $or condition, just concat the empty array and input id,
let res = await usersApi.getrs({
  pagination: false,
  query: {
    "roles.name": "operator",
    _id: { $nin: currentOperatorsIds },
    deletedAt: null,
    entities: { $in: [[], ...id] },
    ...getExpr()
  },
  populate: "entity",
  sort: ["lastName", "firstName"]
});
  1. If you want to improve the regular expression condition you can try the below approach without using $expr and aggregation operators,
  • create a function and set input searchKeyword and searchProperties whatever you want to in array of string

function getSearchContiion(searchKeyword, searchProperties) {
    let query = {};
    if (searchKeyword) {
        query = { "$or": [] };
        const sk = searchKeyword.trim().split(" ").map(n => new RegExp(n, "i"));
        searchProperties.forEach(p => {
            query["$or"].push({ [p]: { "$in": [...sk] } });
        });
    }
    return query;
}
// EX:
console.log(getSearchContiion("John Doe", ["firstName", "lastName"]));

  • Use the above function in query
let res = await usersApi.getrs({
  pagination: false,
  query: Object.assign(
    {
      "roles.name": "operator",
      _id: { $nin: currentOperatorsIds },
      deletedAt: null,
      entities: { $in: [[], ...id] }
    },
    getSearchContiion(value, ["firstName", "lastName"])
  },
  populate: "entity",
  sort: ["lastName", "firstName"]
});
  • Related