node.js - MongoDB聚合,nodejs用AND & OR生成动态查询

标签 node.js typescript mongodb express mongoose

我在我的 nodejs 代码中查询了 MongoDB 的聚合。

const query = {
  '$expr':{
    '$and':[
      {'$eq': ['$appId', req.user.appId]},
    ]
  }
}

从前端接收到一个过滤器对象,如下所示:

{
  shops: '604c776763c302032e610347',
  offset: '0',
  limit: '20',
}

我需要在查询中动态推送商店 ID。需要是 appId -> user.appID AND targetFrom || targetTo <- shops(来自过滤器对象)

商店可以是一个 idid 数组,为此我使用了 $in 运算符

query['$expr']['$and'].push({
  $eq: [
    {
      $or: [
        {"targetFrom": {$in: bb}},
        {"targetTo": {$in: bb}}
      ]
    }
  ]
})

旧版本代码如下:

const query = {
  $and: [
    {appId: req.user.appId}
  ]
}

query['$and'].push({
  $or: [
    {"targetFrom": {$in: bb}}, <- in bb is mongodb objectID
    {"targetTo": {$in: bb}}
  ]
})

更新

如何在我的 items 对象数组中通过 ID 搜索一些 item

if(req.query.products) {
  typeof req.query.products === 'string' ? req.query.products = [req.query.products] : req.query.products
  let bb = req.query.products.map(function(el) { return mongoose.Types.ObjectId(el) })
  query['$expr']['$and'].push({
    $and: [
      {
        items: {
          $in: ['item.itemId', bb]
        }
       }
     ]
   })
}

最佳答案

请查看以下内容是否满足您的要求:

Mongoplayground link

假设:

  1. req.user.appId是一个字符串。
  2. bb是 objectId 或字符串的数组([ObjectId("asdfsd"),ObjectId("badsfds")] 等)
const query = {
  "$expr": {
      $and: [{
        "$eq": ["$appId",req.user.appId],
      }]
      
  }
}

query['$expr']['$and'].push({
  $or: [
    {
      $in: [
        "$targetFrom",
        bb
      ]
    },
    {
      $in: [
        "$targetTo",
        bb
      ]
    }
  ]
})

编辑:要求已更新:获取具有特定 appId 的所有对象,其中targetFromtargetTo是给定数组之一,date介于给定 startDate 之间和 endDate :

Monogplayground

在上面的 mongoplayground 中,我正在获取 appId 所在的所有对象是“1”,startDate2022-01-01 , endDate2022-01-31 bb 是 ["a","c","x"]。这应该获取所有 3 个文档,但是日期过滤掉了第三个文档,因为 date在该文档中是 2021-12-24 .如果您在此之前更改日期,您将获得全部 3 个。

const query = {
  "$expr": {
      $and: [{
        "$eq": ["$appId",req.user.appId],
      }]

  }
}

query['$expr']['$and'] = query['$expr']['$and'].concat([{
          $and: [
            {
              $gte: [
                "$date",
                startDate
              ]
            },
            {
              $lt: [
                "$date",
                endDate
              ]
            }
          ]
        },{
  $or: [
    {
      $in: [
        "$targetFrom",
        bb
      ]
    },
    {
      $in: [
        "$targetTo",
        bb
      ]
    }
  ]
}])

编辑:要求已更新:需要添加 items.id过滤器。

Mongoplayground Link

如果 items 中没有对象,您想要过滤掉文档具有给定的 id,只需添加我在 $and 中添加的额外对象$match stage 中的数组.

{
 $in: [
       1,
       "$items.id",
 ]
}

如果您不想过滤掉此类文档,但想过滤掉 items 中的所有对象items.id在哪里不是给定的 ID,我能找到的唯一解决方案是使用 $project阶段,添加到新的 mongoplayground 链接中。

关于node.js - MongoDB聚合,nodejs用AND & OR生成动态查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70736681/

相关文章:

javascript - 在 Express.js 中使用相同的响应对象发送多个响应

mysql - Express 4.0 和 Mysql 的 PUT 和 DELETE 请求问题

node.js - 如何在 NodeJS 中使用只有 URL 的 Sharp 调整图像大小,使用 async/await,并且没有创建本地副本?

mongodb - 恢复丢失的 WiredTiger.wt

node.js - Mongodb 不返回特定字段

node.js - NodeJS Create 函数崩溃

node.js - 云函数 : Delete file on Cloud Storage when Firestore document is deleted

javascript - Angular 2 - TypeError undefined 不是数组包含的函数

javascript - 在javascript中查找一个值是否属于数组

node.js - 如果不存在如何创建项目并在存在时返回错误