mongodb 如何在字段名称中使用点?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8429318/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 12:21:29  来源:igfitidea点击:

How to use dot in field name?

mongodb

提问by Bdfy

How to use dot in field name ?

如何在字段名称中使用点?

I see error in example:

我在示例中看到错误:

db.test2.insert({ "a.a" : "b" })

can't have . in field names [a.a]

回答by Fisk

You can replace dot symbols of your field name to Unicode equivalent of \uff0E

您可以将字段名称的点符号替换为 Unicode 等效的 \uff0E

db.test.insert({"field\uff0ename": "test"})
db.test.find({"field\uff0ename": "test"}).forEach(printjson)
{ "_id" : ObjectId("5193c053e1cc0fd8a5ea413d"), "field.name" : "test" }

See more:

查看更多:

  1. http://docs.mongodb.org/manual/faq/developers/#faq-dollar-sign-escaping
  2. http://docs.mongodb.org/manual/core/document/#dot-notation
  1. http://docs.mongodb.org/manual/faq/developers/#faq-dollar-sign-escaping
  2. http://docs.mongodb.org/manual/core/document/#dot-notation

回答by lig

Actualy you may use dots in queries. See: http://www.mongodb.org/display/DOCS/Dot+Notation+%28Reaching+into+Objects%29

实际上,您可以在查询中使用点。参见:http: //www.mongodb.org/display/DOCS/Dot+Notation+%28Reaching+into+Objects%29

Because of this special dot symbol mean you cannot use it in field names. Like you cannot use dot symbol in identifiers in most of programming languages.

由于这个特殊的点符号意味着您不能在字段名称中使用它。就像您不能在大多数编程语言的标识符中使用点符号一样。

You may write query db.test2.find({ "a.a" : "b" })but if you want to be able to write such a query you need to insert your object like so: db.test2.insert({"a": {"a": "b"}}). This will create document with the field named "a"with the value of embeded document containing the field named "a"(again) with the value "b".

您可以写信查询db.test2.find({ "a.a" : "b" }),但如果你希望能够写出你需要插入你的对象,像这样这样的查询:db.test2.insert({"a": {"a": "b"}})。这将创建一个文档,其字段命名"a"为嵌入文档的值,其中包含"a"(再次)命名为值的字段"b"

回答by Ziad Sawalha

You can also write a SONManipulatorusing the pymongo library that transforms the data going to and back out of mongodb. There are downsides; there is a performance hit (impact depends on your use case) and you have to transform your keys when you do searches using find.

您还可以使用 pymongo 库编写一个SONManipulator,该库将数据传入和传出 mongodb。有缺点;性能受到影响(影响取决于您的用例),当您使用 find 进行搜索时,您必须转换您的键。

Here's code with an example of how to use it in the comment for the KeyTransform class:

下面的代码包含如何在 KeyTransform 类的注释中使用它的示例:

from pymongo.son_manipulator import SONManipulator

class KeyTransform(SONManipulator):
    """Transforms keys going to database and restores them coming out.

    This allows keys with dots in them to be used (but does break searching on
    them unless the find command also uses the transform).

    Example & test:
        # To allow `.` (dots) in keys
        import pymongo
        client = pymongo.MongoClient("mongodb://localhost")
        db = client['delete_me']
        db.add_son_manipulator(KeyTransform(".", "_dot_"))
        db['mycol'].remove()
        db['mycol'].update({'_id': 1}, {'127.0.0.1': 'localhost'}, upsert=True,
                           manipulate=True)
        print db['mycol'].find().next()
        print db['mycol'].find({'127_dot_0_dot_0_dot_1': 'localhost'}).next()

    Note: transformation could be easily extended to be more complex.
    """

    def __init__(self, replace, replacement):
        self.replace = replace
        self.replacement = replacement

    def transform_key(self, key):
        """Transform key for saving to database."""
        return key.replace(self.replace, self.replacement)

    def revert_key(self, key):
        """Restore transformed key returning from database."""
        return key.replace(self.replacement, self.replace)

    def transform_incoming(self, son, collection):
        """Recursively replace all keys that need transforming."""
        for (key, value) in son.items():
            if self.replace in key:
                if isinstance(value, dict):
                    son[self.transform_key(key)] = self.transform_incoming(
                        son.pop(key), collection)
                else:
                    son[self.transform_key(key)] = son.pop(key)
            elif isinstance(value, dict):  # recurse into sub-docs
                son[key] = self.transform_incoming(value, collection)
        return son

    def transform_outgoing(self, son, collection):
        """Recursively restore all transformed keys."""
        for (key, value) in son.items():
            if self.replacement in key:
                if isinstance(value, dict):
                    son[self.revert_key(key)] = self.transform_outgoing(
                        son.pop(key), collection)
                else:
                    son[self.revert_key(key)] = son.pop(key)
            elif isinstance(value, dict):  # recurse into sub-docs
                son[key] = self.transform_outgoing(value, collection)
        return son

回答by appsdownload

I replaced the key value using myString.replace(".","\u2024") before inserting it into the JsonObject.

在将其插入 JsonObject 之前,我使用 myString.replace(".","\u2024") 替换了键值。

回答by darksider474

I've only really come across this problem when trying to serialize Dictionaries and such where the offending dot can appear as a key name. Edited to show the references.

我只是在尝试序列化字典时才真正遇到过这个问题,比如有问题的点可以作为键名出现。编辑以显示参考。

The quick and dirty C# approach:

快速而肮脏的 C# 方法:

using MongoDB.Bson;
using Newtonsoft.Json.Linq;
using System.Text.RegularExpressions;

public static T Sanitize<T>(T obj)
{
      var str = JObject.FromObject(obj).ToJson();
      var parsed = Regex.Replace(str, @"\.(?=[^""]*"":)", "_");   //i.e. replace dot with underscore when found as a json property name { "property.name": "don't.care.what.the.value.is" }
      return JObject.Parse(parsed).ToObject<T>();
}

回答by tuku

def remove_dots(data):
    for key in data.keys():
        if type(data[key]) is dict: data[key] = remove_dots(data[key])
        if '.' in key:
            data[key.replace('.', '\uff0E')] = data[key]
            del data[key]
    return data

this recursive method replaces all dot characters from keys of a dict with \uff0Eas suggested by Fisk

这种递归方法 按照Fisk 的建议用\uff0E替换 dict 键中的所有点字符

回答by rohit kamal

Initially I used a simple recursion to replace all "." characters with its unicode equivalent but figured it out that even the dots in the values was getting replaced. So I thought that we should replace the dots only from keys and made the changes accordingly in case "if isinstance(input, dict)". I thought it should be a sufficient condition to do the magic but I forgot that dict value can also be a dict or a list and then I finally added that check that if value of a dict was not string then, go inside recursively and was finally able to come up with this solution which eventually did the trick.

最初我使用一个简单的递归来替换所有的“.”。字符与其 unicode 等效,但发现即使是值中的点也被替换了。所以我认为我们应该只从键中替换点,并在“if isinstance(input, dict)”的情况下进行相应的更改。我认为这应该是实现魔法的充分条件,但我忘记了 dict 值也可以是 dict 或列表,然后我最后添加了检查,如果 dict 的值不是字符串,则递归地进入并最终能够提出这个最终成功的解决方案。

def remove_dots(data):
    if isinstance(data, dict):
            return {remove_dots(key): value if isinstance(value, str) else remove_dots(value) for key,value in data.iteritems()}
    elif isinstance(data, list):
            return [remove_dots(element) for element in data]
    elif isinstance(data, str):
            return data.replace('.','\u002e')
    else:                                                                                             
            return data