首页 > 解决方案 > 如何在 find() 上链接 Mongoose model.find()

问题描述

这是在 Node.js 方法中分两步过滤 mongoDb 集合的方法。我正在使用猫鼬。

步骤 1:首先根据用户的角色过滤集合

步骤2:在步骤1的过滤结果上,根据搜索字符串进一步过滤和/或选择前端选择的选项。

下面是编写的代码,但在 .find() 查询结果上应用 .find() 作为链不起作用。每当应用第二步时,过滤后的结果不符合第一步。

请提出最佳替代方案

async function getServiceLog(fy, filter, sortKey, sortOrder, pageSize, pageIndex, filtObj, user){
  let fetchedDocs;
  let docQuery;

//// STEP 1
  if(user.role === 'Admin' || user.managesAll === true) {
    // display all documents
    docQuery = ServiceLog.find({FY: fy}).collation({ locale: 'en'});

  } else if(user.isManager === true) {
    // display documents where execName = userName or approver = userName or execName is in user.team

    docQuery = ServiceLog.find({
      $and: [
        { FY: fy},
        {
          $or: [
            { execName: user.userName },
            { approver: user.userName },
            { rm: { $regex:  user.userName, $options: 'i' } },
            { execName: { $in:  user.team.map(u => u.userName) } },
          ]
        }
      ]
    });

  } else if(!user.isManager || user.isManager === false) {
    // display documents where execName = userName or approver = userName

    docQuery = ServiceLog.find({
      $and: [
        { FY: fy},
        {
          $or: [
            { execName: user.userName },
            { approver: user.userName },
            { rm: { $regex:  user.userName, $options: 'i' } },
          ],
        }
      ]
      });
  }

//// STEP 2
  let filtType = 'none';

  if(filter && filtObj.length <= 0) {
    filtType = 'filter'
  } else if(!filter && filtObj.length > 0) {
    filtType = 'filtObj'
  } else if(filter && filtObj.length > 0) {
    filtType = 'both'
  }

  switch(filtType) {
    case "none":
      break;

    case "filter":
      docQuery = docQuery.find({                    // <<<< Second .find()
        $or: [
          { compName: { $regex:  filter, $options: 'i' } },
          { servName: { $regex:  filter, $options: 'i' } },
        ],
        }).collation({ locale: 'en'});
      break;

    case "filtObj":
      docQuery = docQuery.find({                       // <<<< Second .find()
            $and: filtObj
        }).collation({ locale: 'en'});
      break;

    case "both":
      docQuery = docQuery.find({                       // <<<< Second .find()
        $and: [
          {
            $or: [
              { compName: { $regex:  filter, $options: 'i' } },
              { servName: { $regex:  filter, $options: 'i' } },
            ],
          },
          {
            $and: filtObj
          }
        ]
        }).collation({ locale: 'en'});
      break;
  }


/// STEP 3: Finalize the result by applying sort and pagination
  ///// this is to find out the count of documents matching the search/filter criteria
  //// as later this will get trimmed due to page size
  fetchedDocs = await docQuery;
  if(!fetchedDocs) fetchedDocs = [];

  totalCount = fetchedDocs.length;
  if(!totalCount) totalCount = 0;


  if(totalCount > 0) {
    if(pageSize && pageIndex >= 0) {
      if(!sortKey) {
        docQuery.skip(pageSize * pageIndex).limit(pageSize);
      }else{
        if(sortOrder === 'desc') {
          sortOption = '-' + sortKey
        }else {
          sortOption = sortKey
        }
        docQuery.sort(sortOption).skip(pageSize * pageIndex).limit(pageSize);
      }
    }
    fetchedDocs = await docQuery;
  }

  if(!fetchedDocs) fetchedDocs = [];

  servLogData = {
    servicelogs: fetchedDocs,
    totalCount: totalCount
  }
  
  return servLogData;
}

标签: node.jsmongodbmongoose

解决方案


推荐阅读