为复杂对象扩展BSON`$ type`属性?
我想在MongoDB中存储对象。这些对象来自第三方系统,具有非常特定的格式,即所有的对象属性都存储在字典中。这个字典中的值可以是不同的类型,并且没有特定的顺序。
我相信要有效地搜索这些领域,我需要把它们变成BSON属性。自定义串行器/解串器可以实现它,直到涉及到反序列化本身。如果属性是一个表示为BSON文档的复杂对象,则自定义deseriazer不知道该文档应转换为哪种类型。
如何使用MongoDB BSON以正确的方式解决这些问题?
我会将新的属性$type
添加到复杂文档,并在序列化期间存储目标类型,但它会干扰MongoDB $type
属性中的构建。
是否可以并排使用标准和自定义$type
属性?在这种情况下实现自定义解串器的最佳实践方法是什么?
不是没有扩展规范本身,或包括一些参考文件本身应该如何(德)序列化。
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的缺点,使得查询超出子类型检查非常困难。
除此之外的任何东西都会涉及到扩展规格本身