【问题标题】:MongoDB not allowing using '.' in key [duplicate]MongoDB 不允许使用 '.'在关键[重复]
【发布时间】:2015-04-24 05:19:21
【问题描述】:

我正在尝试保存包含特殊字符“.”的字典在 MongoDB 的关键部分。错误如下所示,明确指出密钥不能包含特殊字符'.'。

>>> import pymongo
>>> client = pymongo.MongoClient('localhost')
>>> db = client['malware']                                                                                                                                                          
>>> test = db['test']
>>> d = {'.aaa' : '.bbb'}                                                                                                                                                           
>>> test.insert(d)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib64/python2.7/site-packages/pymongo/collection.py", line 362, in insert
    self.database.connection)
bson.errors.InvalidDocument: key '.aaa' must not contain '.'

但我当前的信息包含“。”在数据的关键部分,我需要存储到 MongoDB。目前我只是删除'。从字符串中,另一种选择是将其替换为“_”或其他一些特殊字符。

尽管如此,所有这些都会导致信息丢失,因为如果我有一个键 '.aaa' 和一个键 'aaa' 并且如果我转换 '.'进入 '' 然后键完全一样,我丢失了一些信息。为什么 Mongo 不允许我将“.aaa”保存到数据库中?

任何想法如何解决这个问题?

【问题讨论】:

    标签: python mongodb


    【解决方案1】:

    可以根据source设置check_keys为False:

     test.insert(d,check_keys=False)
    
    
     def insert(self, doc_or_docs, manipulate=True,
               safe=None, check_keys=True, continue_on_error=False, **kwargs):
    

    确实有效:

    In [28]: d = {'.aaa' : '.bbb'}
    
    In [29]: test.insert(d,check_keys=False)
    Out[29]: ObjectId('54ea604bf9664e211e8ed4e6')
    

    文档字符串说明:

    • check_keys(可选):如果 True 检查键是否以 '$' 开头 或包含“.”,在任何一种情况下都会引发 :class:~pymongo.errors.InvalidName

    您似乎可以使用除了两个$. 之外的任何字符,因此前导下划线或任何其他字符都可以,并且可能是更好的选择。

    常见问题中有关于escaping 的信息:

    在某些情况下,您可能希望使用用户提供的密钥构建 BSON 对象。在这些情况下,密钥需要替换保留的 $ 和 .人物。任何字符都足够,但请考虑使用 Unicode 全宽等效字符:U+FF04(即“$”)和 U+FF0E(即“.”)。

    点符号常见问题解答解释了为什么使用. 不是一个好主意:

    MongoDB 使用点符号来访问数组的元素和访问嵌入文档的字段。 要通过从零开始的索引位置访问数组的元素,请将数组名称与点 (.) 和从零开始的索引位置连接起来,并用引号引起来:

    【讨论】:

    • 感谢您让我知道此选项。您能否简要描述一下为什么 Mongo 不允许您使用 '.' 保存密钥?默认情况下,您必须覆盖它才能做到这一点?这将给出一个完整的答案,并实际解释为什么会发生这种情况,之后我可以接受这个答案是正确的。再次感谢。
    • insert() 已弃用,取而代之的是没有 check_keys 参数的 insert_one()。它有一个bypass_document_validation 参数,但这没有相同的效果,它仍然不会插入一个键中有一个点的文档。
    • check_keys 不再可用。
    • @coding_idiot : 那么有什么选择呢?
    【解决方案2】:

    您不能使用“.aaa”作为密钥,因为 Mongo 使用点来引用 nested documents

    如果你想让键看起来像一个点,你可以使用像\u002E这样的unicode等价物:

    >>> d = {'\u002Eaaa' : '\u002Ebbb'}    
    

    但是,我建议您选择另一个角色并将其视为平台的“限制”。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-22
      • 1970-01-01
      • 2018-08-31
      • 2013-08-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多