我有以下数据架构:
{
"Address" : "Test1",
"City" : "London",
"Country" : "UK",
"Currency" : "",
"Price_History" : {
"2014-07-04T02:42:58" : [
{
"value1" : 98,
"value2" : 98,
"value3" : 98
}
],
"2014-07-04T03:50:50" : [
{
"value1" : 91,
"value2" : 92,
"value3" : 93
}
]
},
"Location" : [
9.3435,
52.1014
],
"Postal_code" : "xxx"
}
如何在mongodb中生成查询以搜索“2014-07-04T02:42:58”和“2014-07-04T03:50:50”<之间的所有结果/ strong>或如何生成查询以仅选择值 91 的结果,直到 93 >> 才知道日期?
感谢
答案 0 :(得分:1)
不是一个非常好的方法来模拟这个。一个更好的例子如下:
{
"Address" : "Test1",
"City" : "London",
"Country" : "UK",
"Currency" : "",
"Price_History" : [
{ "dateEnrty": 1, "date": ISODate("2014-07-04T02:42:58Z"), "value": 98 },
{ "dateEntry": 2, "date": ISODate("2014-07-04T02:42:58Z"), "value": 98 },
{ "dateEntry": 3, "date": ISODate("2014-07-04T02:42:58Z"), "value": 98 },
{ "dateEntry": 1, "date": ISODate("2014-07-04T03:50:50Z"), "value": 91 },
{ "dateEntry": 2, "date": ISODate("2014-07-04T03:50:50Z"), "value": 92 },
{ "dateEntry": 3, "date": ISODate("2014-07-04T03:50:50Z"), "value": 93 },
],
"Location" : [
9.3435,
52.1014
],
"Postal_code" : "xxx"
}
或者那些不利用路径依赖的行。这里的查询相对简单,但也考虑到MongodDB搜索文档而不是数组这样的东西。但您可以使用聚合框架进行剖析:
db.collection.aggregate([
// Still match first to reduce the possible documents
{ "$match": {
"Price_History": {
"$elemMatch": {
"date": {
"$gte": ISODate("2014-07-04T02:42:58Z"),
"$lte": ISODate("2014-07-04T03:50:50Z")
},
"value": 98
}
}
}},
// Unwind to "de-normalize"
{ "$unwind": "$Price_History" },
// Match this time to "filter" the array which is now documents
{ "$match": {
"Price_History.date": {
"$gte": ISODate("2014-07-04T02:42:58Z"),
"$lte": ISODate("2014-07-04T03:50:50Z")
},
"Price_Hisotry.value": 98
}},
// Now group back each document with the matches
{ "$group": {
"_id": "$_id",
"Address": { "$first": "$Address" },
"City": { "$first": "$City" },
"Country": { "$first": "$Country" },
"Currency": { "$first": "$Currency" },
"Price_History": { "$push": "$Price_History" },
"Location": { "$first": "$Location" },
"Postal_Code": { "$first": "$Postal_Code" }
}}
])
或者更好地暂停“规范化”,只需选择您可以通过标准.find()
处理的离散文档。必须更快更简单。
{
"Address" : "Test1",
"City" : "London",
"Country" : "UK",
"Currency" : "",
"date": ISODate("2014-07-04T02:42:58Z"),
"value": 98
}
等。那么只需查询:
db.collection.find({
"date": {
"$gte": ISODate("2014-07-04T02:42:58Z"),
"$lte": ISODate("2014-07-04T03:50:50Z")
},
"value": 98
})
我真的会将其作为“非规范化的”“Price History”集合,因为它更有效,基本上是聚合语句的模拟。
你要求的查询可以使用像MongoDB mapReduce那样评估JavaScript的东西,但正如我已经说过的那样,将需要在没有任何索引帮助的情况下扫描整个集合,这很糟糕
将你的案子交给老板重新塑造并立即获得奖金。