2014-07-04 184 views
0

,我有以下數據模式:查詢日期範圍

{ 
     "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」或者如何生成查詢以僅選擇結果值爲至 沒有要知道日期?

感謝

+1

你的日期不僅有效地字符串,而且本質上是文檔的「關鍵」。由於「關鍵路徑」是固定的,因此這不是一種很好的建模方法。考慮重新建模,或者堅持JavaScript評估,與本地方法相比,JavaScript評估速度要慢得多。 –

+1

您最好更改您的模式,以便price_history是一個數組,然後使日期成爲該日期的定價信息中的一個字段,然後使用匯總框架$ unwind生成結果 – Sammaye

+0

不幸的是,我不有任何選擇來改變架構 – ovntatar

回答

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 
}) 

我真的會與去當「去標準化」 「價格歷史」收集,因爲它是更加有效,基本上什麼彙總語句正在模擬。

。你要的查詢可以使用的東西,評估的JavaScript像MongoDB的MapReduce的,但正如我已經說過,它需要掃描整個收藏沒有任何指數的援助,這是不好的。

把你的情況給老闆重新建模,並獲得你的獎金吧。

+0

太好了,我會提供你的建議,順便說一句怎麼看起來像查詢,如果我有一個即{「value.com」:98},因爲在這種情況下,你的建議{「Price_Hisotry.value。 com「:98}不起作用,或者如果我不知道關鍵字」value.com「,看起來如何看起來像查詢?再次thx – ovntatar

+0

@ovntatar沒有一個明確的例子有點過於寬泛的評論。嘗試在這裏的方法,如果你有另一個問題,然後張貼一個,我相信有人會回答。 –