如何根据 mongo 集合的嵌套文档中字符串日期字段的日期范围检索数据

How to retrieve data based on the date range of string date field in a nested document of a mongo collection

高级要求:

我有一个特殊的要求,我想 return 在某些日期之间售出特定类型 属性 的特定项目。

详细要求

我有项目集合,我们在其中存储所有项目相关数据。该集合包含不同的部分,其中一个部分处理该项目中所有类型属性的销售日期信息。

所以现在我想拉出“别墅”类型在“2018-10-01”(YYYY-mm-dd)和“2019-09-30”(YYYY-mm-dd)之间销售的项目.

我的带有示例数据的集合结构

db.getCollection('projects').find({})

{
    "_id" : "11a2c36923fe24da490f81626742234f",
    "project" : "highlands_1.0",
    "project_sale_schedule" : [ 
        {
            "project_type" : "Condo",
            "dates" : "2019-06-13"
        }, 
        {
            "project_type" : "Apartment",
            "dates" : "2019-07-11"
        }, 
        {
            "project_type" : "Villa",
            "dates" : "2019-07-11",
            "comments" : "No issues"
        }, 
        {
            "project_type" : "Open Plot"
        }, 
        {
            "project_type" : "Fenced Plot",
            "dates" : "2019-10-15"
        }
    ],
    "repay_schedule" : [ 
        {
            "project_type" : "Condo",
            "installment1" : "2019-11-15",
            "installment2" : "2019-11-01",
            "installment3" : "2019-10-25",
            "installment4" : "2019-10-14"
        }, 
        {
            "project_type" : "Apartment",
            "installment1" : "2019-12-20",
            "installment2" : "2019-12-06",
            "installment3" : "2019-11-29",
            "installment4" : "2019-11-15"
        }, 
        {
            "project_type" : "Villa",
            "installment1" : "2020-03-10",
            "installment2" : "2020-03-10",
            "installment3" : "2020-03-10",
            "installment4" : "2020-02-26"
        }, 
        {
            "project_type" : "Fenced Plot",
            "installment1" : "2020-03-27",
            "installment2" : "2020-03-20"
        }
    ],
    "lease_pay_schedule" : [ 
        {
            "project_type" : "Condo",
            "req_date_installment1" : "2019-10-21",
            "req_date_installment2" : "2019-10-14"
        }, 
        {
            "project_type" : "Apartment",
            "req_date_installment1" : "2019-11-15",
            "req_date_installment2" : "2019-11-01"
        }, 
        {
            "project_type" : "Villa",
            "req_date_installment1" : "2020-01-03",
            "req_date_installment2" : "2019-12-20"
        }, 
        {
            "project_type" : "Fenced Plot",
            "req_date_installment1" : "2020-03-24",
            "req_date_installment2" : "2020-03-10",
            "comments" : "3 days before HM synth start"
        }
    ]
},
{
    "_id" : "11a2c36923fe24da490f81626742234f",
    "project" : "green_fields_1.0",
    "project_sale_schedule" : [ 
        {
            "project_type" : "Condo",
            "dates" : "2019-06-13"
        }, 
        {
            "project_type" : "Apartment",
            "dates" : "2019-07-11"
        }, 
        {
            "project_type" : "Villa",
            "dates" : "2020-07-11"
        }, 
        {
            "project_type" : "Open Plot"
        }, 
        {
            "project_type" : "Fenced Plot",
            "dates" : "2019-10-15"
        }
    ],
    "repay_schedule" : [ 
        {
            "project_type" : "Condo",
            "installment1" : "2019-11-15",
            "installment2" : "2019-11-01",
            "installment3" : "2019-10-25",
            "installment4" : "2019-10-14"
        }, 
        {
            "project_type" : "Apartment",
            "installment1" : "2019-12-20",
            "installment2" : "2019-12-06",
            "installment3" : "2019-11-29",
            "installment4" : "2019-11-15"
        }, 
        {
            "project_type" : "Villa",
            "installment1" : "2020-03-10",
            "installment2" : "2020-03-10",
            "installment3" : "2020-03-10",
            "installment4" : "2020-02-26"
        }, 
        {
            "project_type" : "Fenced Plot",
            "installment1" : "2020-03-27",
            "installment2" : "2020-03-20"
        }
    ],
    "lease_pay_schedule" : [ 
        {
            "project_type" : "Condo",
            "req_date_installment1" : "2019-10-21",
            "req_date_installment2" : "2019-10-14"
        }, 
        {
            "project_type" : "Apartment",
            "req_date_installment1" : "2019-11-15",
            "req_date_installment2" : "2019-11-01"
        }, 
        {
            "project_type" : "Villa",
            "req_date_installment1" : "2020-01-03",
            "req_date_installment2" : "2019-12-20"
        }, 
        {
            "project_type" : "Fenced Plot",
            "req_date_installment1" : "2020-03-24",
            "req_date_installment2" : "2020-03-10",
            "comments" : "3 days before HM synth start"
        }
    ]
},
{
    "_id" : "11a2c36923fe24da490f81626742234f",
    "project" : "green_fields_2.0",
    "project_sale_schedule" : [ 
        {
            "project_type" : "Condo",
            "dates" : "2019-06-13"
        }, 
        {
            "project_type" : "Apartment",
            "dates" : "2019-07-11"
        }, 
        {
            "project_type" : "Villa"
        }, 
        {
            "project_type" : "Open Plot"
        }, 
        {
            "project_type" : "Fenced Plot",
            "dates" : "2019-10-15"
        }
    ],
    "repay_schedule" : [ 
        {
            "project_type" : "Condo",
            "installment1" : "2019-11-15",
            "installment2" : "2019-11-01",
            "installment3" : "2019-10-25",
            "installment4" : "2019-10-14"
        }, 
        {
            "project_type" : "Apartment",
            "installment1" : "2019-12-20",
            "installment2" : "2019-12-06",
            "installment3" : "2019-11-29",
            "installment4" : "2019-11-15"
        }, 
        {
            "project_type" : "Villa",
            "installment1" : "2020-03-10",
            "installment2" : "2020-03-10",
            "installment3" : "2020-03-10",
            "installment4" : "2020-02-26"
        }, 
        {
            "project_type" : "Fenced Plot",
            "installment1" : "2020-03-27",
            "installment2" : "2020-03-20"
        }
    ],
    "lease_pay_schedule" : [ 
        {
            "project_type" : "Condo",
            "req_date_installment1" : "2019-10-21",
            "req_date_installment2" : "2019-10-14"
        }, 
        {
            "project_type" : "Apartment",
            "req_date_installment1" : "2019-11-15",
            "req_date_installment2" : "2019-11-01"
        }, 
        {
            "project_type" : "Villa",
            "req_date_installment1" : "2020-01-03",
            "req_date_installment2" : "2019-12-20"
        }, 
        {
            "project_type" : "Fenced Plot",
            "req_date_installment1" : "2020-03-24",
            "req_date_installment2" : "2020-03-10",
            "comments" : "3 days before HM synth start"
        }
    ]
},
{
    "_id" : "11a2c36923fe24da490f81626742234f",
    "project" : "high_value_1.0",
    "project_sale_schedule" : [ 
        {
            "project_type" : "Condo",
            "dates" : "2019-06-13"
        }, 
        {
            "project_type" : "Apartment",
            "dates" : "2019-07-11"
        }, 
        {
            "project_type" : "Villa",
            "dates" : "2019-09-11"
        }, 
        {
            "project_type" : "Open Plot"
        }, 
        {
            "project_type" : "Fenced Plot",
            "dates" : "2019-10-15"
        }
    ],
    "repay_schedule" : [ 
        {
            "project_type" : "Condo",
            "installment1" : "2019-11-15",
            "installment2" : "2019-11-01",
            "installment3" : "2019-10-25",
            "installment4" : "2019-10-14"
        }, 
        {
            "project_type" : "Apartment",
            "installment1" : "2019-12-20",
            "installment2" : "2019-12-06",
            "installment3" : "2019-11-29",
            "installment4" : "2019-11-15"
        }, 
        {
            "project_type" : "Villa",
            "installment1" : "2020-03-10",
            "installment2" : "2020-03-10",
            "installment3" : "2020-03-10",
            "installment4" : "2020-02-26"
        }, 
        {
            "project_type" : "Fenced Plot",
            "installment1" : "2020-03-27",
            "installment2" : "2020-03-20"
        }
    ],
    "lease_pay_schedule" : [ 
        {
            "project_type" : "Condo",
            "req_date_installment1" : "2019-10-21",
            "req_date_installment2" : "2019-10-14"
        }, 
        {
            "project_type" : "Apartment",
            "req_date_installment1" : "2019-11-15",
            "req_date_installment2" : "2019-11-01"
        }, 
        {
            "project_type" : "Villa",
            "req_date_installment1" : "2020-01-03",
            "req_date_installment2" : "2019-12-20"
        }, 
        {
            "project_type" : "Fenced Plot",
            "req_date_installment1" : "2020-03-24",
            "req_date_installment2" : "2020-03-10",
            "comments" : "3 days before HM synth start"
        }
    ]
}

当我运行查询时我感兴趣的最终输出是

**Result:**

{
    "project" : "highlands_1.0"
},
{
    "project" : "high_value_1.0"
}

or

["highlands_1.0", "high_value_1.0"]

注意: 我不想要项目 "green_fields_1.0","green_fields_2.0",因为 Villa 类型 属性 的销售不在日期范围内或日期不存在。

我遇到了 post 。它处理与我的问题类似的事情,但我收集的数据结构使我无法聚合数据。

我的Mongo版本:3.6.2

这似乎有效。诀窍是使用 $filter 然后 $match 过滤数组的大小。输出比您要求的多一点,但您可以轻松添加另一个项目以删除 X 数组。

var sdate = ISODate("2018-10-01");
var edate = ISODate("2019-09-30");

c = db.foo.aggregate([
    {$project: {
    project: true,  // carry the project field into the output...
    X: {$filter: {
            input: "$project_sale_schedule",
            as: "zz",
            cond: {$and:[
                {$eq: ['$$zz.project_type',"Villa"]}
                ,{$gte: [{$dateFromString: { dateString: "$$zz.dates", format: "%Y-%m-%d"}},sdate]}
                ,{$lt: [{$dateFromString: { dateString: "$$zz.dates", format: "%Y-%m-%d"}},edate]}
            ]
                  }
        }}
    }}
    ,{$match: {$expr: {$gt: [ {$size:"$X"}, 0 ] }}}
]);

有一个更高级的版本,它使用 $let 允许我们将字符串转换为日期一次。注意:如果您可以在文档中使用实际的日期时间类型而不是字符串,这可能是个好主意。

        X: {$filter: {
            input: "$project_sale_schedule",
            as: "zz",
            cond: {$let: {
                vars: {dd: {$dateFromString: { dateString: "$$zz.dates", format: "%Y-%m-%d"}}},
                in: {$and:[
                    {$eq: ['$$zz.project_type',"Villa"]}
                    ,{$gte: ["$$dd",sdate]}
                    ,{$lt: ["$$dd",edate]}
                ]}
            }}

        }}
    }}