【问题标题】:How to retrieve data based on the date range of string date field in a nested document of a mongo collection如何根据 mongo 集合的嵌套文档中字符串日期字段的日期范围检索数据
【发布时间】:2022-01-13 10:37:03
【问题描述】:

高级要求:

我有一个特殊要求,我想退回在某些日期之间售出特定类型财产的特定项目。

详细要求

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

所以现在我想拉出“别墅”类型在“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",因为出售 别墅 属性类型不在日期范围内或日期不存在。

我看到了here 的帖子。它处理与我的问题类似的问题,但我的集合的数据结构使我无法聚合数据。

我的 Mongo 版本: 3.6.2

【问题讨论】:

    标签: mongodb mongodb-query aggregation-framework mongo-collection


    【解决方案1】:

    这似乎有效。诀窍是在过滤数组的大小上使用$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]}
                    ]}
                }}
    
            }}
        }}
    

    【讨论】:

    • 谢谢@Buzz Moschetti。它就像一个魅力。这里有一个注释。因为我使用的是 Mongo 版本 3.6.2。我必须从“$dateFromString”选项中去掉“格式”。由于“格式”不是 Mongo 3.6“$dateFromString”版本的一部分。去除X的附加投影也是一个好点。你节省了我很多时间。还有一个注意事项。我确实遵循日期字段的日期。由于这是一个旧数据库,并且最初使用字符串日期抽取了大量数据。我对此无能为力。就是这样。再次感谢。
    猜你喜欢
    • 2014-05-11
    • 2016-10-27
    • 1970-01-01
    • 2018-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-01
    • 1970-01-01
    相关资源
    最近更新 更多