我如何为多个集合做 Mongodb 聚合过滤器? [英] How can i do Mongodb aggrigate filter for multiple collection?

查看:49
本文介绍了我如何为多个集合做 Mongodb 聚合过滤器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个收集预订和发票,我准备了以下条件的汇总和查找查询

I have two collection bookings and invoices and I have prepared aggregate and lookup query for below condition

预订收集条件

条件 1:状态不等于已送达

条件 2:产品不能为 null 或为空

条件 3:ProductID 应该存在于 products 数组中,并且不能为空

条件 4:IsDeliveryFailed 不应为是"

预订收集数据

{
    "_id" : ObjectId("609a382b589346973c84c6fe"),
    "Name" : "abc",
    "UserId":1
    "Status" : "Pending", 
    "Invoices" : [ 
        ObjectId("709a382b5c6fe89346973c84")
    ],  
    "BookingData" : {
        "Date" : ISODate("2021-04-30T04:00:00.000Z"),
        "info" : [],
        "BookingDataMethod" : "avf",
        "Message" : null,
        "products" : [ 
            {
                "_id" : ObjectId("60a4e92775e5de3570578820"),
                "ProductName" : "Test1",
                "ProductID" : ObjectId("60a4e92475e5de357057880a"),
                "IsDeliveryFailed" : "Yes"
            }, 
            {
                "_id" : ObjectId("60a4e92775e5de357057881f"),
                "ProductName" : "Test2",
                "ProductID" : ObjectId("60a4e92475e5de357057880d")
            }
        ],
        
    }
    
}

发票收集条件

条件 1:InvoiceData 不应为 null 或为空

条件 2:InvoiceID 应存在于 InvoiceData 数组中,且不应为空

条件 3:IsPaymentFailed 不应为是"

发票收集数据

{
    "_id" : ObjectId("709a382b5c6fe89346973c84"),    
    "invoiceNumber":1
    "InvoiceData" :[
            {
                "_id" : ObjectId("60a4e92775e5de3570578820"),
                "ProductName" : "Test1",
                "InvoiceID":1,
                "IsPaymentFailed" : "Yes"
            }, 
            {
                "_id" : ObjectId("60a4e92775e5de357057881f"),
                "InvoiceID":2,
                "ProductName" : "Test2",
                
            }
    
    ]
    
}

查询

db.bookings.aggregate([
  {
    "$match": {
      "Status": {
        $ne: "Delivered"
      }
    }
  },
  {
    "$lookup": {
      "from": "invoices",
      "localField": "Invoices",
      "foreignField": "_id",
      "as": "invoiceInfo"
    }
  },
  {
    "$match": {
      "$or": [
        {
          "BookingData.products": {
            "$exists": true
          }
        },
        {
          "invoiceInfo.InvoiceData": {
            "$exists": true
          }
        }
      ]
    }
  },
 {
    $set: {
      "BookingData.products": {
        "$filter": {
          "input": "$BookingData.products",
          "cond": {
            $and: [
              { $ne: [ "$$this.ProductID", undefined ] },
              { $ne: [ "$$this._id", null ] },
              { $ne: [ "$$this.IsDeliveryFailed", "Yes" ] }
            ]
          }
        }
      }
    }
  },
 {
    $set: {
      "invoiceInfo.InvoiceData": {
        "$filter": {
          "input": "$invoiceInfo.InvoiceData",
          "cond": {
            $and: [
              { $ne: [ "$$this.InvoiceID", undefined ] },
              { $ne: [ "$$this._id", null ] },
              { $ne: [ "$$this.IsPaymentFailed", "Yes" ] }
            ]
          }
        }
      }
    }
  },
  {
    $match: {
      $expr: {
        $or: [
          {
            $ne: [
              "$BookingData.products",
              [],
              
            ]
          },
          {
            $ne: [
              "$invoiceInfo.InvoiceData",
              [],
              
            ]
          }
        ]
      }
    }
  }
  
])

这不能按预期工作,例如如果

this is not working as expected for example if

查询应该返回上面的文档

The query should return the above document

如果 ProductID 存在且产品存在且所有产品都没有 IsDeliveryFailed:是"

if ProductID exist and products exist and all products do not have IsDeliveryFailed: "Yes"

如果 ProductID 存在且产品存在且任何产品都没有 IsDeliveryFailed:是"

if ProductID exist and products exist and anyone products do not have IsDeliveryFailed: "Yes"

如果 InvoiceID 存在且 InvoiceData 存在且所有 InvoiceData 都没有 IsPaymentFailed:是"

if InvoiceID exist and InvoiceData exist and all InvoiceData do not have IsPaymentFailed: "Yes"

如果 InvoiceID 存在且 InvoiceData 存在且任何 InvoiceData 没有 IsPaymentFailed:是"

if InvoiceID exist and InvoiceData exist and anyone InvoiceData does not has IsPaymentFailed: "Yes"

另一套

如果 ProductID 存在且产品存在且所有产品都为 IsDeliveryFailed:是";旗帜.但我们必须检查发票收集如果 InvoiceID 存在并且 InvoiceData 存在并且任何 InvoiceData 没有 IsPaymentFailed:是"那么我们必须返回这个文件

if ProductID exists and products exist and all products are IsDeliveryFailed: "Yes" flag. but we have to check invoices collection if InvoiceID exist and InvoiceData exist and anyone InvoiceData does not have IsPaymentFailed: "Yes" then we have to return this document

如果 InvoiceID 存在且 InvoiceData 存在且所有 InvoiceData 均为 IsPaymentFailed:是".但我们必须检查预订集合如果 ProductID 存在且产品存在且任何产品都没有 IsDeliveryFailed:是"那么我们必须返回文档

if InvoiceID exist and InvoiceData exist and all InvoiceData are IsPaymentFailed: "Yes".but we have to check bookings collection if ProductID exist and products exist and anyone products does not have IsDeliveryFailed:"Yes" then we have to returndocument

Mongo 游乐场

推荐答案

我已经在问题中解释了您之前的问题.由于invoiceInfo 是一个数组,而invoiceData 也是invoiceInfo 中的一个数组,我们使用map 和filter.然后我们需要排除 invoiceData 的空数组.(这也可以在上一步完成,就像 filter-map->filter 一样,但它可能很长,这就是我在下一阶段使用它的原因)

I have explained your previous problem in Question. Since the invoiceInfo is an array and invoiceData also an array inside invoiceInfo, we use map and filter. Then we need to exclude empty array of invoiceData. (This can be done in previous step also like filter-map->filter, but it could be lengthy, thats why I used it in next stage )

这是代码

db.bookings.aggregate([
  {
    "$match": {
      "PaymentStatus": { $ne: "Delivered" }
    }
  },
  {
    $set: {
      "BookingData.products": {
        "$filter": {
          "input": "$BookingData.products",
          "cond": {
            $and: [
              { $ne: [ "$$this.ProductID", undefined ] },
              { $ne: [ "$$this._id", null ] },
              { $ne: [ "$$this.IsDeliveryFailed", "Yes" ] }
            ]
          }
        }
      }
    }
  },
  {
    "$lookup": {
      "from": "invoices",
      "localField": "Invoices",
      "foreignField": "_id",
      "as": "invoiceInfo"
    }
  },
  {
    $set: {
      invoiceInfo: {
        $map: {
          input: "$invoiceInfo",
          as: "info",
          in: {
            InvoiceData: {
              $filter: {
                input: "$$info.InvoiceData",
                as: "data",
                "cond": {
                  $and: [
                    { $ne: [ "$$data.InvoiceID", undefined ] },
                    { $ne: [ "$$data.InvoiceID", null ] },
                    { $ne: [ "$$data.IsPaymentFailed", "Yes" ] }
                  ]
                }
              }
            }
          }
        }
      }
    }
  },
  {
    $set: {
      invoiceInfo: {
        $filter: {
          input: "$invoiceInfo",
          cond: { $ne: [ "$$this.InvoiceData", [] ] }
        }
      }
    }
  },
  {
    $match: {
      $expr: {
        $or: [
          { $ne: [ "$BookingData.products", [] ] },
          { $ne: [ "$invoiceInfo", [] ] }
        ]
      }
    }
  }
])

工作 Mongo 游乐场

希望对你有帮助.这是您需要根据您的要求播放/解决方法的时间.有时你需要在demo中的当前位置之前或之后进行查找

Hope this will help you. This is the time you need to play/ workaround based on your requirement. Sometimes you need to do lookup before or after the current location in demo

这篇关于我如何为多个集合做 Mongodb 聚合过滤器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆