我有一个名为member_transaction的集合。示例文档结构如下:
{
"memberId": "XY-123",
"transactionsDetails": {
"2015-07-15": [
{
"memberId": "1011",
"orderId": "232",
"topLevelcategory": "household",
"orderValue": "34313.200"
},
{
"memberId": "1011",
"orderId": "235",
"topLevelcategory": "Furniture",
"orderValue": "2534.200"
}
],
"2015-07-16": [
{
"memberId": "1011",
"orderId": "235",
"topLevelcategory": "Furniture",
"orderValue": "2534.200"
},
{
"memberId": "1012",
"orderId": "235",
"topLevelcategory": "Grocery",
"orderValue": "2534.200"
},
{
"memberId": "1013",
"orderId": "235",
"topLevelcategory": "Grocery",
"orderValue": "2534.200"
},
{
"memberId": "1014",
"orderId": "235",
"topLevelcategory": "Grocery",
"orderValue": "2534.200"
}
],
"2015-07-18": [
{
"memberId": "2011",
"orderId": "1232",
"topLevelcategory": "household",
"orderValue": "34313.200"
},
{
"memberId": "103",
"orderId": "2352",
"topLevelcategory": "Furniture",
"orderValue": "2534.200"
}
],
"2015-07-19": [
{
"memberId": "311",
"orderId": "152",
"topLevelcategory": "household",
"orderValue": "34313.200"
},
{
"memberId": "1013",
"orderId": "2312",
"topLevelcategory": "Furniture",
"orderValue": "2534.200"
},
{
"memberId": "1043",
"orderId": "2316",
"topLevelcategory": "Grocery",
"orderValue": "2534.200"
},
{
"memberId": "1017",
"orderId": "2315",
"topLevelcategory": "Furniture",
"orderValue": "2544"
}
]
}
}
如何查询在两个密钥之间具有数组结构的mongoDB,即如何在密钥"2015-07-16"
&之间提取数据。上述文件中的"2015-07-19"
?
答案 0 :(得分:1)
查询具有动态密钥的此类架构将非常困难。更好的推荐方法是重新设计模式,使得嵌入式文档具有保存日期值的date
键和存储数组的transactionDetails
键。以下演示了理想的架构更改:
db.member_transaction.insert({
"memberId": "XY-123",
"transactions": [
{
"date": ISODate("2015-07-15"),
"transactionsDetails": [
{
"memberId": "1011",
"orderId": "232",
"topLevelcategory": "household",
"orderValue": "34313.200"
},
{
"memberId": "1011",
"orderId": "235",
"topLevelcategory": "Furniture",
"orderValue": "2534.200"
}
]
},
{
"date": ISODate("2015-07-16"),
"transactionsDetails": [
{
"memberId": "1011",
"orderId": "235",
"topLevelcategory": "Furniture",
"orderValue": "2534.200"
},
{
"memberId": "1012",
"orderId": "235",
"topLevelcategory": "Grocery",
"orderValue": "2534.200"
},
{
"memberId": "1013",
"orderId": "235",
"topLevelcategory": "Grocery",
"orderValue": "2534.200"
},
{
"memberId": "1014",
"orderId": "235",
"topLevelcategory": "Grocery",
"orderValue": "2534.200"
}
]
},
{
"date": ISODate("2015-07-18"),
"transactionsDetails": [
{
"memberId": "2011",
"orderId": "1232",
"topLevelcategory": "household",
"orderValue": "34313.200"
},
{
"memberId": "103",
"orderId": "2352",
"topLevelcategory": "Furniture",
"orderValue": "2534.200"
}
]
},
{
"date": ISODate("2015-07-19"),
"transactionsDetails": [
{
"memberId": "311",
"orderId": "152",
"topLevelcategory": "household",
"orderValue": "34313.200"
},
{
"memberId": "1013",
"orderId": "2312",
"topLevelcategory": "Furniture",
"orderValue": "2534.200"
},
{
"memberId": "1043",
"orderId": "2316",
"topLevelcategory": "Grocery",
"orderValue": "2534.200"
},
{
"memberId": "1017",
"orderId": "2315",
"topLevelcategory": "Furniture",
"orderValue": "2544"
}
]
}
]
})
使用上面的架构,您可以使用 aggregation framework 查询具有该日期范围的文档。以下聚合管道将实现所需的结果:
db.member_transaction.aggregate([
{
"$match": {
"transactions.date": {
"$gte": ISODate("2015-07-16T00:00:00.000Z"),
"$lte": ISODate("2015-07-19T00:00:00.000Z")
}
}
},
{
"$unwind": "$transactions"
},
{
"$match": {
"transactions.date": {
"$gte": ISODate("2015-07-16T00:00:00.000Z"),
"$lte": ISODate("2015-07-19T00:00:00.000Z")
}
}
},
{
"$group": {
"_id": null,
"memberId": { "$first": "$memberId" },
"transactions": { "$push": "$transactions" }
}
}
])
示例输出:
/* 0 */
{
"result" : [
{
"_id" : null,
"memberId" : "XY-123",
"transactions" : [
{
"date" : ISODate("2015-07-16T00:00:00.000Z"),
"transactionsDetails" : [
{
"memberId" : "1011",
"orderId" : "235",
"topLevelcategory" : "Furniture",
"orderValue" : "2534.200"
},
{
"memberId" : "1012",
"orderId" : "235",
"topLevelcategory" : "Grocery",
"orderValue" : "2534.200"
},
{
"memberId" : "1013",
"orderId" : "235",
"topLevelcategory" : "Grocery",
"orderValue" : "2534.200"
},
{
"memberId" : "1014",
"orderId" : "235",
"topLevelcategory" : "Grocery",
"orderValue" : "2534.200"
}
]
},
{
"date" : ISODate("2015-07-18T00:00:00.000Z"),
"transactionsDetails" : [
{
"memberId" : "2011",
"orderId" : "1232",
"topLevelcategory" : "household",
"orderValue" : "34313.200"
},
{
"memberId" : "103",
"orderId" : "2352",
"topLevelcategory" : "Furniture",
"orderValue" : "2534.200"
}
]
},
{
"date" : ISODate("2015-07-19T00:00:00.000Z"),
"transactionsDetails" : [
{
"memberId" : "311",
"orderId" : "152",
"topLevelcategory" : "household",
"orderValue" : "34313.200"
},
{
"memberId" : "1013",
"orderId" : "2312",
"topLevelcategory" : "Furniture",
"orderValue" : "2534.200"
},
{
"memberId" : "1043",
"orderId" : "2316",
"topLevelcategory" : "Grocery",
"orderValue" : "2534.200"
},
{
"memberId" : "1017",
"orderId" : "2315",
"topLevelcategory" : "Furniture",
"orderValue" : "2544"
}
]
}
]
}
],
"ok" : 1
}
<强>更新强>
您可以使用 $elemMatch
投影运算符来限制查询结果中字段的内容,但不能仅使用第一个元素匹配 $elemMatch
条件(即具有日期transactionDetails
的{{1}}数组文档),因此聚合框架是首选方法,因为它返回所有期望的结果。 / p>
以下内容还演示了 $elemMatch
运算符在您的示例中的工作原理:
"2015-07-16"
示例输出:
db.member_transaction.find(
{
"transactions.date": {
"$gte": ISODate("2015-07-16T00:00:00.000Z"),
"$lte": ISODate("2015-07-19T00:00:00.000Z")
}
},
{
"memberId": 1,
"transactions": {
"$elemMatch": {
"date": {
"$gte": ISODate("2015-07-16T00:00:00.000Z"),
"$lte": ISODate("2015-07-19T00:00:00.000Z")
}
}
}
}
)