2017-04-09 21 views
1

我想在MongoDB中存儲對象。這些對象來自第三方系統,具有非常特定的格式,即所有的對象屬性都存儲在字典中。這個字典中的值可以是不同的類型,並且沒有特定的順序。

我相信要有效地搜索這些領域,我需要把它們變成BSON屬性。自定義串行器/解串器可以實現它,直到涉及到反序列化本身。如果屬性是一個表示爲BSON文檔的複雜對象,則自定義deseriazer不知道該文檔應轉換爲哪種類型。

如何使用MongoDB BSON以正確的方式解決這些問題?

我會將新的屬性$type添加到複雜文檔,並在序列化期間存儲目標類型,但它會干擾MongoDB $type屬性中的構建。

是否可以並排使用標準和自定義$type屬性?在這種情況下實現自定義解串器的最佳實踐方法是什麼?

回答

1

不是沒有擴展規範本身,或包括一些參考文件本身應該如何(德)序列化。

PHP驅動程序有一個ODM框架,它確實是你正在提議的。我建議你看看http://php.net/manual/en/class.mongodb-bson-persistable.php

在系列化,司機將注入包含PHP類名__pclass財產 到數據

所以,它增加了一個specifc鍵「__pclass」的文件被存儲。在反序列化過程中,驅動程序從關鍵字中讀取關鍵字,以決定採用什麼特定的反序列化步驟,並在將__pclass鍵/值返回給用戶之前將文檔(現在反序列化爲由__pclass鍵指定的任何PHP類)去除。

如果您有任何理由不相信mongodb中保存的數據,這是非常危險的。它基本上允許數據決定對可執行PHP代碼的調用。

關於規格本身。 http://bsonspec.org/spec.html

類型及其關聯的類型索引被硬編碼到規範中。

element  ::=  "\x01" e_name double 64-bit binary floating point 
    | "\x02" e_name string UTF-8 string 
    | "\x03" e_name document Embedded document 
    | "\x04" e_name document Array 
    | "\x05" e_name binary Binary data 
    | "\x06" e_name Undefined (value) — Deprecated 
    | "\x07" e_name (byte*12)  ObjectId 
    | "\x08" e_name "\x00" Boolean "false" 
    | "\x08" e_name "\x01" Boolean "true" 
    | "\x09" e_name int64  UTC datetime 
    | "\x0A" e_name Null value 
    | "\x0B" e_name cstring cstring Regular expression - The first cstring is the regex pattern, the second is the regex options string. Options are identified by characters, which must be stored in alphabetical order. Valid options are 'i' for case insensitive matching, 'm' for multiline matching, 'x' for verbose mode, 'l' to make \w, \W, etc. locale dependent, 's' for dotall mode ('.' matches everything), and 'u' to make \w, \W, etc. match unicode. 
    | "\x0C" e_name string (byte*12) DBPointer — Deprecated 
    | "\x0D" e_name string JavaScript code 
    | "\x0E" e_name string Symbol. Deprecated 
    | "\x0F" e_name code_w_s JavaScript code w/ scope 
    | "\x10" e_name int32  32-bit integer 
    | "\x11" e_name uint64 Timestamp 
    | "\x12" e_name int64  64-bit integer 
    | "\x13" e_name decimal128 128-bit decimal floating point 
    | "\xFF" e_name Min key 
    | "\x7F" e_name Max key 

如果存儲在BLOB中的二進制塊,使用用戶定義的亞型範圍內,您可以創建生成的二進制亞型自己的用戶。

binary ::=  int32 **subtype** (byte*) Binary - The int32 is the number of bytes in the (byte*). 

subtype  ::=  "\x00" Generic binary subtype 
    | "\x01" Function 
    | "\x02" Binary (Old) 
    | "\x03" UUID (Old) 
    | "\x04" UUID 
    | "\x05" MD5 
    | **"\x80" User defined** 

存在將對象存儲在數據庫中作爲二進制blob的缺點,使得查詢超出子類型檢查非常困難。

除此之外的任何東西都會涉及到擴展規格本身