根据嵌套最多和嵌套最少的数组 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 上试用。
在这种情况下,如果能提供任何帮助,我将不胜感激。 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 上试用。