如何根据 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]}
]}
}}
}}
}}
高级要求:
我有一个特殊的要求,我想 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]}
]}
}}
}}
}}