2013-06-21 115 views
1

我的應用程序以JSON格式生成日誌。日誌看起來像這樣:將ISODate字符串轉換爲mongoDB本地ISODate數據類型

{"LogLevel":"error","Datetime":"2013-06-21T11:20:17Z","Module":"DB","Method":"ExecuteSelect","Request":"WS_VALIDATE","Error":"Procedure or function 'WS_VALIDATE' expects parameter '@LOGIN_ID', which was not supplied."} 

目前,我推入上述日誌行,因爲它是進入mongoDB。但是mongoDB將Datetime存儲爲一個字符串(這是預期的)。現在我想在這些日誌上運行一些數據處理作業,我寧願將Datetime存儲爲mongoDB的本地ISODate數據類型。

有3種方法我能想到的這樣做:

我)解析每個JSON日誌線和轉換線在應用程序代碼,以ISODate類型,然後將其插入。缺點:我將不得不解析每一行,然後推送到mongoDB,這將是一個有點貴

ii)每個插入後運行查詢將最後插入的文檔的字符串日期時間轉換爲使用ISODate

element.Datetime = ISODate(element.Datetime); 

缺點:同樣昂貴的,因爲我會在運行每個刀片 III中的一個額外的查詢)修改我在生成點日誌,以便我不必在應用程序代碼級別做任何分析,或每次插入後運行更新查詢

此外,只是好奇,有沒有一種方法可以配置mongoDB自動將日期時間字符串轉換爲其本機isodate格式?

TIA

編輯: 我使用pymongo用於插入JSON日誌

我的文件看起來是這樣的:

{ 「LogLevel的」: 「錯誤」, 「日期時間」: 「2013-06-21T11:20:17Z」,「模塊」:「DB」,「方法」:「ExecuteSelect」,「請求」:「WS_VALIDATE」,「錯誤」:「過程或函數'WS_VALIDATE'期望參數' @LOGIN_ID',它沒有提供。「}

有數百行像一個mentio以上內容。 這是我如何將它們插入到MongoDB的:

for line in logfile: 
    collection.insert(json.loads(line)) 

下面將解決我的問題:

for line in logfile: 
    data = json.loads(line) 
    data["Datetime"] = datetime.strptime(data["Datetime"], "%Y-%M-%DTHH:mmZ") 
    collection.insert(data) 

我想要做的就是擺脫日期時間的額外操縱我的什麼我不得不這樣做。希望能夠澄清這個問題。

+0

您可以控制應用程序 - 爲什麼不從ISODate生成日期並從頭開始存儲? –

+0

謝謝@AsyaKamsky。我的應用程序生成日誌並將它們作爲文件存儲在其特定的服務器上。這些日誌被移動到一箇中央日誌存儲服務器,從那裏我把日誌推送到mongoDB。日誌文件在字符串中有ISODate格式的時間,但是當我將日誌推送到mongoDB時,它將時間數據作爲一個字符串。 – texens

+0

通過使用批量插入並將文檔附加到數組中,然後在數組中包含X條目時插入,可以減少插入的數量。 – Ross

回答

0

這取決於您推送日誌的語言/驅動程序/實用程序。我假設你正在使用mongoimport

mongoimport不支持ISODate()。參考此問題https://jira.mongodb.org/browse/SERVER-5543 ISODate()不是JSON格式,因此在mongoimport中不受支持。 i)方法似乎更有效率。 ii)在mongo上執行兩個操作:插入&更新。在將某些日誌數據導入到mongo時,我遇到了同樣的問題。我最終將ISO 8601格式日期轉換爲紀元格式。

{"LogLevel":"error","Datetime":{"$date" : 1371813617000},"Module":"DB","Method":"ExecuteSelect","Request":"WS_VALIDATE","Error":"Procedure or function 'WS_VALIDATE' expects parameter '@LOGIN_ID', which was not supplied."} 

上面的JSON應該可以工作。請注意,它是64位而不是32位的紀元。

+0

我使用pymongo,用Python推送日誌。我已經添加了一個小代碼樣本,說明我目前正在做什麼。 – texens

+0

您鏈接的問題不是正確的問題 - 正確的問題是https://jira.mongodb.org/browse/SERVER-5675並且已修復此問題。 –

1

此外,只是好奇,有沒有一種方法可以配置mongoDB自動將日期時間字符串轉換爲其本機isodate格式?

您可能想要爲時間戳創建Python datetime對象,並使用PyMongo插入該對象。這是作爲MongoDB中的本地日期對象存儲的。

因此,例如在Python:

from datetime import datetime 
object_with_timestamp = { "timestamp": datetime.now() } 
your_collection.insert(object_with_timestamp) 

當這個對象被從蒙戈外殼質疑,一個ISODate對象存在:

"timestamp" : ISODate("2013-06-24T09:29:58.615Z")

2

看起來你已經有答案...我會堅持:

for line in logfile: 
    data = json.loads(line) 
    data["Datetime"] = datetime.strptime(data["Datetime"], "%Y-%M-%DTHH:mmZ") 
    collection.insert(data) 

我有一個類似的問題,但我並沒有預先知道我應該用datetime對象替換它。所以我改變了我的JSON信息是這樣的:

{"LogLevel":"error","Datetime":{"__timestamp__": "2013-06-21T11:20:17Z"},"Module":"DB","Method":"ExecuteSelect","Request":"WS_VALIDATE","Error":"Procedure or function 'WS_VALIDATE' expects parameter '@LOGIN_ID', which was not supplied."} 

和解析JSON有:

json.loads(data, object_hook=logHook) 

與 'logHook' 定義爲:

def logHook(d): 
    if '__timestamp__' in d: 
     return datetime.strptime(d['__timestamp__'], "%Y-%M-%DTHH:mmZ") 
    return d 

logHook功能也被擴展以用elif,elif,...

012替代許多其他「變量」

希望這有助於!

相關問題