如何根据第一个和最后一个嵌套数组中的值过滤包含具有 3 级嵌套数组的文档的集合中的数据 mongo

How to filter data in collection containing documents with 3 level nested arrays depending on the values in the first and last nested array mongo

在这种情况下,我很感激任何帮助。 MongoDB 中的集合(现在只有 4 个文档用于演示目的):

   { 
    "_id" : ObjectId("62684847e9594c65cbaa5d85"), 
    "agentId" : NumberInt(1), 
    "agentName" : "Yardi Gaondi", 
    "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-01-19T05:46:15.000+0000")
                        }
                    ]
                }
            ]
        }, 
        {
            "receivedDate" : ISODate("2022-03-23T04:46:15.000+0000"), 
            "policyStatusDetail" : [
                {
                    "policyStsCode" : NumberInt(7), 
                    "policiesArray" : [
                        {
                            "policyDetailedCode" : NumberInt(3), 
                            "policyStatusDate" : ISODate("2022-01-16T04:46:15.000+0000")
                        }
                    ]
                }
            ]
        }, 
        {
            "receivedDate" : ISODate("2022-02-23T04:46:15.000+0000"), 
            "policyStatusDetail" : [
                {
                    "policyStsCode" : NumberInt(7), 
                    "policiesArray" : [
                        {
                            "policyDetailedCode" : NumberInt(1), 
                            "policyStatusDate" : ISODate("2022-01-20T04:46:15.000+0000")
                        }, 
                        {
                            "policyDetailedCode" : NumberInt(2), 
                            "policyStatusDate" : ISODate("2022-01-19T05:46:15.000+0000")
                        }
                    ]
                }
            ]
        }
    ]
}
{ 
    "_id" : ObjectId("62684847e9594c65cbaa5d86"), 
    "agentId" : NumberInt(2), 
    "agentName" : "Michelle Hazandi", 
    "policyList" : [
        {
            "receivedDate" : ISODate("2022-04-10T04:46:15.000+0000"), 
            "policyStatusDetail" : [
                {
                    "policyStsCode" : NumberInt(7), 
                    "policiesArray" : [
                        {
                            "policyDetailedCode" : NumberInt(2), 
                            "policyStatusDate" : ISODate("2022-04-09T05:46:15.000+0000")
                        }
                    ]
                }
            ]
        }, 
        {
            "receivedDate" : ISODate("2022-03-10T04:46:15.000+0000"), 
            "policyStatusDetail" : [
                {
                    "policyStsCode" : NumberInt(7), 
                    "policiesArray" : [
                        {
                            "policyDetailedCode" : NumberInt(2), 
                            "policyStatusDate" : ISODate("2022-03-09T05:46:15.000+0000")
                        }
                    ]
                }
            ]
        }
    ]
}
{ 
    "_id" : ObjectId("626da96932cb6043086eae42"), 
    "agentId" : NumberInt(3), 
    "agentName" : "Barbie", 
    "policyList" : [
        {
            "receivedDate" : ISODate("2022-04-23T04:46:15.000+0000"), 
            "policyStatusDetail" : [
                {
                    "policyStsCode" : NumberInt(7), 
                    "policiesArray" : [
                        {
                            "policyDetailedCode" : NumberInt(1), 
                            "policyStatusDate" : ISODate("2022-05-20T04:46:15.000+0000")
                        }, 
                        {
                            "policyDetailedCode" : NumberInt(2), 
                            "policyStatusDate" : ISODate("2022-01-19T05:46:15.000+0000")
                        }
                    ]
                }
            ]
        }, 
        {
            "receivedDate" : ISODate("2022-02-23T04:46:15.000+0000"), 
            "policyStatusDetail" : [
                {
                    "policyStsCode" : NumberInt(7), 
                    "policiesArray" : [
                        {
                            "policyDetailedCode" : NumberInt(3), 
                            "policyStatusDate" : ISODate("2022-05-16T04:46:15.000+0000")
                        }
                    ]
                }
            ]
        }, 
        {
            "receivedDate" : ISODate("2022-01-23T04:46:15.000+0000"), 
            "policyStatusDetail" : [
                {
                    "policyStsCode" : NumberInt(7), 
                    "policiesArray" : [
                        {
                            "policyDetailedCode" : NumberInt(1), 
                            "policyStatusDate" : ISODate("2022-03-20T04:46:15.000+0000")
                        }, 
                        {
                            "policyDetailedCode" : NumberInt(2), 
                            "policyStatusDate" : ISODate("2022-01-19T05:46:15.000+0000")
                        }
                    ]
                }
            ]
        }
    ]
}
{ 
    "_id" : ObjectId("626da96932cb6043086eae43"), 
    "agentId" : NumberInt(4), 
    "agentName" : "Mzandi", 
    "policyList" : [
        {
            "receivedDate" : ISODate("2022-05-10T04:46:15.000+0000"), 
            "policyStatusDetail" : [
                {
                    "policyStsCode" : NumberInt(7), 
                    "policiesArray" : [
                        {
                            "policyDetailedCode" : NumberInt(2), 
                            "policyStatusDate" : ISODate("2022-02-09T05:46:15.000+0000")
                        }
                    ]
                }
            ]
        }, 
        {
            "receivedDate" : ISODate("2022-01-10T04:46:15.000+0000"), 
            "policyStatusDetail" : [
                {
                    "policyStsCode" : NumberInt(7), 
                    "policiesArray" : [
                        {
                            "policyDetailedCode" : NumberInt(2), 
                            "policyStatusDate" : ISODate("2022-02-09T05:46:15.000+0000")
                        }
                    ]
                }
            ]
        }
    ]
}

所以集合由4个文档组成,每个文档中都有一个字段“policyList”,它是一个对象数组。在第一个文档中 policyList 包含 3 个对象,在第二个文档中只有两个,依此类推。所以我必须以这种方式过滤这个集合中的文档:1)我需要在“policyList”数组中只保留那些符合这种条件的对象:其中一个字段在某个时间间隔内,这意味着必须是至少一个字段中的匹配项(第一个字段是“receivedDate”——位于第一层嵌套的数组中——“policyList”或第二个字段“policyStatusDate”——位于第三层数组中嵌套 - “policiesArray”,如果上述字段之一匹配,我们 return 来自“policyList”完整对象,这意味着我们不能从“policiesArray”中丢弃任何对象)。一次匹配就足够了,例如,如果我想查看从 01/02/2022 到 01/03/2022 的文档,我希望在“policyList”数组的第一个文档中只看到第一个和第三个对象,因为第一个对象匹配“policyStatusDate” - 20/02/2022(匹配“policiesArray”中的一个对象就足够了)和第三个对象匹配“receivedDate” - 23/02/2022)和第一个文档中的第二个对象我不希望请参阅,因为本文档中的两个日期都不在 01/02/2022 到 01/03/2022 期间; 2)如果“policyList”中的对象之间没有任何匹配项,则意味着“policyList”在过滤后必须为空,在这种情况下我们不需要return这个文档。例如,如果我请求从 01/02/2022 到 01/03/2022 的文档,我不希望看到第二个文档,因为在请求的时间间隔内没有“policyStatusDate”和“receivedDate”。

我的聚合请求:

db.getCollection("offers2").aggregate([
{
  $project: {
  "agentId": "$agentId",
  "agentName": "$agentName",
  "policyList": {
      $filter: {
         input: "$policyList",
         as: "item",
         cond: {
         "$or": [
            {
              "$and": [
                { "$gte": [ "$$item.receivedDate", ISODate("2022-02-01") ] },
                { "$lte": [ "$$item.receivedDate", ISODate("2022-03-01") ] }
              ]
            }, 
            {
               $and": [
                { "$gte": [ "$$item.policyStatusDetail.policiesArray.policyStatusDate", ISODate("2022-02-01") ] },
                { "$lte": [ "$$item.policyStatusDetail.policiesArray.policyStatusDate", ISODate("2022-03-01") ] }
              ]
            }
         ]
         }
      }
  }
  }
},
{
  $project: {
  "agentId": "$agentId",
  "agentName": "$agentName",
  "policyList": "$policyList",
  "numPoliciesPerDate": {
    $cond: {  
      if: {$isArray: "$policyList"}, then: {$size: "$policyList"}, else: "0"
     }
    }
  }
  },
  {
  $match: {
    "numPoliciesPerDate": {$gte: 1}
     }
  }
]) 

在 运行 这个查询之后,我希望在“policyList”数组中收到带有第一个对象和第三个对象的第一个文档,但我只收到第三个对象(此对象中有“receivedDate”匹配)。结果:

{ 
    "_id" : ObjectId("62684847e9594c65cbaa5d85"), 
    "agentId" : NumberInt(1), 
    "agentName" : "Yardi Gaondi", 
    "policyList" : [
        {
            "receivedDate" : ISODate("2022-02-23T04:46:15.000+0000"), 
            "policyStatusDetail" : [
                {
                    "policyStsCode" : NumberInt(7), 
                    "policiesArray" : [
                        {
                            "policyDetailedCode" : NumberInt(1), 
                            "policyStatusDate" : ISODate("2022-01-20T04:46:15.000+0000")
                        }, 
                        {
                            "policyDetailedCode" : NumberInt(2), 
                            "policyStatusDate" : ISODate("2022-01-19T05:46:15.000+0000")
                        }
                    ]
                }
            ]
        }
    ], 
    "numPoliciesPerDate" : NumberInt(1)
}

... 所以看起来条件

 $and": [
                { "$gte": [ "$$item.policyStatusDetail.policiesArray.policyStatusDate", ISODate("2022-02-01") ] },
                { "$lte": [ "$$item.policyStatusDetail.policiesArray.policyStatusDate", ISODate("2022-03-01") ] }
              ]

不正确。我认为这是因为当我们使用嵌套数组时可能无法使用点符号。所以也许有人可以帮我修复这个聚合查询,这样我在开头描述的要求就会得到满足,在我们的例子中,第一个文档中“policyList”的第一个对象也将被 returned?

我认为这个可以解决问题,只需将日期替换为您所在时区的正确格式即可:

[
  {
    $unwind: {
      path: "$policyList"
    }
  },
  {
    $match: {
      $or: [
        {
          "policyList.receivedDate": {
            $gte: ISODate("2022-02-01T03:00:00.000Z"),
            $lte: ISODate("2022-03-01T03:00:00.000Z")
          }
        },
        {
          "policyList.policyStatusDetail.policiesArray.policyStatusDate": {
            $gte: ISODate("2022-02-01T03:00:00.000Z"),
            $lte: ISODate("2022-03-01T03:00:00.000Z")
          }
        }
      ]
    }
  },
  {
    $group: {
      _id: "$_id",
      agentId: {
        $first: "$agentId"
      },
      agentname: {
        $first: "$agentName"
      },
      policyList: {
        $push: {
          receivedDate: "$policyList.receivedDate",
          policyStatusDetail: "$policyList.policyStatusDetail"
        }
      }
    }
  },
  {
    $project: {
      "agentId": "$agentId",
      "agentName": "$agentName",
      "policyList": "$policyList",
      "numPoliciesPerDate": {
        $cond: {
          if: {
            $isArray: "$policyList"
          },
          then: {
            $size: "$policyList"
          },
          else: "0"
        }
      }
    }
  },
  {
    $match: {
      "numPoliciesPerDate": {
        $gte: 1
      }
    }
  }
]
db.collection.aggregate(
  { "$set": {
      "policyList": {
        "$filter": {
          "input": "$policyList",
          "as": "policy",
          "cond": {
            "$or": [
              { "$and": [
                  { "$gte": [ "$$policy.receivedDate", ISODate("2022-02-01") ] },
                  { "$lte": [ "$$policy.receivedDate", ISODate("2022-03-01") ] }
                ]
              },
              { "$reduce": {
                  "input": "$$policy.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") ] }
                              ]
                            }
                            ]
                          }
                        }
                      }
                    ]
                  }
                }
              }
            ]
          }
        }
      }
    }
  },
  { "$match": { "$expr": { "$gt": [ { "$size": "$policyList" }, 0 ] } } }
)

mongoplayground