根据嵌套最多和嵌套最少的数组 mongoDB 中的值过滤包含三级嵌套数组的文档

filtering documents containing three level nested arrays depending on the values in the most nested and least nested array mongoDB

在这种情况下,如果能提供任何帮助,我将不胜感激。 MongoDB 中的集合(现在只有 3 个对象用于演示目的):

{ 
    "_id" : ObjectId("62684847e9594c65cbaa5d85"), 
    "agentId" : NumberInt(1), 
    "agentName" : "Digital Queen", 
    "policyList" : [
        {
            "receivedDate" : ISODate("2022-03-23T04:46:15.000+0000"), 
            "policyStatusDetail" : [
                {
                    "policyStsCode" : NumberInt(7), 
                    "policiesArray" : [
                        {
                            "policyDetailedCode" : NumberInt(1), 
                            "policyStatusDate" : ISODate("2022-02-20T04:46:15.000+0000")
                        }, 
                        {
                            "policyDetailedCode" : NumberInt(2), 
                            "policyStatusDate" : ISODate("2022-02-19T05:46:15.000+0000")
                        }
                    ]
                }
            ]
        }, 
        {
            "receivedDate" : ISODate("2022-01-23T04:46:15.000+0000"), 
            "policyStatusDetail" : [
                {
                    "policyStsCode" : NumberInt(7), 
                    "policiesArray" : [
                        {
                            "policyDetailedCode" : NumberInt(3), 
                            "policyStatusDate" : ISODate("2022-02-16T04:46:15.000+0000")
                        }
                    ]
                }
            ]
        }
    ]
}
{ 
    "_id" : ObjectId("62684847e9594c65cbaa5d86"), 
    "agentId" : NumberInt(2), 
    "agentName" : "Iron Lady", 
    "policyList" : [
        {
            "receivedDate" : ISODate("2022-02-23T04:46:15.000+0000"), 
            "policyStatusDetail" : [
                {
                    "policyStsCode" : NumberInt(7), 
                    "policiesArray" : [
                        {
                            "policyDetailedCode" : NumberInt(2), 
                            "policyStatusDate" : ISODate("2022-03-03T05:46:15.000+0000")
                        }
                    ]
                }
            ]
        }
    ]
}
{ 
    "_id" : ObjectId("62684847e9594c65cbaa5d87"), 
    "agentId" : NumberInt(3), 
    "agentName" : "Proxy Agent", 
    "policyList" : [
        {
            "receivedDate" : ISODate("2022-04-10T04:46:15.000+0000"), 
            "policyStatusDetail" : [
                {
                    "policyStsCode" : NumberInt(1), 
                    "policiesArray" : [
                        {
                            "policyDetailedCode" : NumberInt(3), 
                            "policyStatusDate" : ISODate("2022-04-09T05:46:15.000+0000")
                        }
                    ]
                }
            ]
        }
    ]
}

我只需要 return 那些只在特定时间段内的文档。至少有一个字段必须匹配:1) “receivedDate”(位于第一层嵌套的数组 - policyList 中)或 2) “policyStatusDate”(位于第三层数组中)嵌套 - policiesArray)。一次匹配就足够了,例如,如果我想查看从 01/02/2022 到 01/03/2022 的文档,我希望看到第一个和第二个文档(第一个文档与 policyStatusDate - 20/02/2022 匹配,第二个文档匹配by receivedDate - 23/02/2022) 和我不希望看到的第三份文件,因为这份文件中的两个日期都是从四月开始的。

我的聚合请求:

db.getCollection("offers").aggregate([
{
  $project: {
  "agentId": "$agentId",
  "agentName": "$agentName",
  "policyList": {
        $map: {
                input: "$policyList",
                as: "policies",
                in:  {
                  receivedDate: "$$policies.receivedDate",
                  policyStatusDetail: {
                    $map: {
                     input: "$$policies.policyStatusDetail",
                     as: "items",
                     in: {
                         policyStsCode: "$$items.policyStsCode",
                         policiesArray: {
                           $filter: {
                             input: "$$items.policiesArray",
                             as: "item",
                             cond: {
                               $or: [
                                {$and: [{$gte: ["$$policies.receivedDate", ISODate("2022-02-01")]},
                                    {$lte: ["$$policies.receivedDate", ISODate("2022-03-31")]}
                                    ]
                                    },
                                
                                {$and: [
                                    {$gte: ["$$item.policyStatusDate", ISODate("2022-02-01")]},
                                    {$lte: ["$$item.policyStatusDate", ISODate("2022-03-31")]}
                                    ]}
                                ]
                             }
                           }
                         }
                      }
                    }
                  }
                }
        } 
    }
  }

}
])

我收到了所有 3 份文件,而不仅仅是第一份和第二份文件。我收到了包含所有字段的第三份文档,并且字段 policiesArray(数组类型)为空(作为我查询的结果)。如果此数组为空,则表示该文档不在请求的时间段内,因为它没有通过检查。但我不需要看这份文件。 结果:

{ 
    "_id" : ObjectId("62684847e9594c65cbaa5d85"), 
    "agentId" : NumberInt(1), 
    "agentName" : "Digital Queen", 
    "policyList" : [
        {
            "receivedDate" : ISODate("2022-03-23T04:46:15.000+0000"), 
            "policyStatusDetail" : [
                {
                    "policyStsCode" : NumberInt(7), 
                    "policiesArray" : [
                        {
                            "policyDetailedCode" : NumberInt(1), 
                            "policyStatusDate" : ISODate("2022-02-20T04:46:15.000+0000")
                        }, 
                        {
                            "policyDetailedCode" : NumberInt(2), 
                            "policyStatusDate" : ISODate("2022-02-19T05:46:15.000+0000")
                        }
                    ]
                }
            ]
        }, 
        {
            "receivedDate" : ISODate("2022-01-23T04:46:15.000+0000"), 
            "policyStatusDetail" : [
                {
                    "policyStsCode" : NumberInt(7), 
                    "policiesArray" : [
                        {
                            "policyDetailedCode" : NumberInt(3), 
                            "policyStatusDate" : ISODate("2022-02-16T04:46:15.000+0000")
                        }
                    ]
                }
            ]
        }
    ]
}
{ 
    "_id" : ObjectId("62684847e9594c65cbaa5d86"), 
    "agentId" : NumberInt(2), 
    "agentName" : "Iron Lady", 
    "policyList" : [
        {
            "receivedDate" : ISODate("2022-02-23T04:46:15.000+0000"), 
            "policyStatusDetail" : [
                {
                    "policyStsCode" : NumberInt(7), 
                    "policiesArray" : [
                        {
                            "policyDetailedCode" : NumberInt(2), 
                            "policyStatusDate" : ISODate("2022-03-03T05:46:15.000+0000")
                        }
                    ]
                }
            ]
        }
    ]
}
{ 
    "_id" : ObjectId("62684847e9594c65cbaa5d87"), 
    "agentId" : NumberInt(3), 
    "agentName" : "Proxy Agent", 
    "policyList" : [
        {
            "receivedDate" : ISODate("2022-04-10T04:46:15.000+0000"), 
            "policyStatusDetail" : [
                {
                    "policyStsCode" : NumberInt(1), 
                    "policiesArray" : [

                    ]
                }
            ]
        }
    ]
}

所以我的问题是我需要在查询中添加什么来避免return使用空的 policiesArray(第三嵌套级别数组)访问文档?也许还有更好的选择如何正确进行此查询?

编辑:完成重做以修复逻辑(希望如此)

匹配阶段只需要一个 true/false,因此嵌套 "$reduce" 可以深入到每个数组元素和 evaluate/aggregate 条件。

db.collection.aggregate({
  "$match": {
    "$expr": {
      "$reduce": {
        "input": "$policyList",
        "initialValue": false,
        "in": {
          "$or": [
            "$$value",
            {
              "$and": [
                { "$gte": [ "$$this.receivedDate", ISODate("2022-02-01") ] },
                { "$lte": [ "$$this.receivedDate", ISODate("2022-03-01") ] }
              ]
            },
            {
              "$reduce": {
                "input": "$$this.policyStatusDetail",
                "initialValue": false,
                "in": {
                  "$or": [
                    "$$value",
                    {
                      "$reduce": {
                        "input": "$$this.policiesArray",
                        "initialValue": false,
                        "in": {
                          "$or": [
                            "$$value",
                            {
                              "$and": [
                                { "$gte": [ "$$this.policyStatusDate", ISODate("2022-02-01") ] },
                                { "$lte": [ "$$this.policyStatusDate", ISODate("2022-03-01") ] }
                              ]
                            }
                          ]
                        }
                      }
                    }
                  ]
                }
              }
            }
          ]
        }
      }
    }
  }
})

mongoplayground.net 上试用。