programing

필드 이름에서 점을 사용하는 방법은 무엇입니까?

instargram 2023. 7. 6. 21:47
반응형

필드 이름에서 점을 사용하는 방법은 무엇입니까?

필드 이름에서 점을 사용하는 방법은 무엇입니까?

예를 들어 다음과 같은 오류가 표시됩니다.

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

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

필드 이름의 점 기호를 다음과 같은 유니코드로 바꿀 수 있습니다.\uff0E

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

더 보기:

  1. http://docs.mongodb.org/manual/faq/developers/ #1500달러 간판 광고
  2. http://docs.mongodb.org/manual/core/document/ #도트 웹사이트

실제로 쿼리에서 점을 사용할 수 있습니다.참조: http://www.mongodb.org/display/DOCS/Dot+Notation+%28Reaching+into+Objects%29

이 특수한 점 기호로 인해 필드 이름에 사용할 수 없습니다.대부분의 프로그래밍 언어에서 식별자에 점 기호를 사용할 수 없는 것처럼.

조회를 작성할 수 있습니다.db.test2.find({ "a.a" : "b" })그러나 이러한 쿼리를 작성하려면 다음과 같이 개체를 삽입해야 합니다.db.test2.insert({"a": {"a": "b"}})이름이 지정된 필드로 문서를 만듭니다."a"이름이 지정된 필드를 포함하는 포함된 문서의 값으로"a"(다시) 가치가 있는"b".

또한 mongodb로 가거나 mongodb에서 나오는 데이터를 변환하는 pymongo 라이브러리를 사용하여 SON Manipulator를 작성할 수 있습니다.단점도 있습니다. 성능이 저하되고(사용 사례에 따라 영향이 있음) find를 사용하여 검색할 때 키를 변환해야 합니다.

다음은 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
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

이 재귀적 방법은 딕트 키의 모든 점 문자를 피스크가 제안한 대로 \uff0E로 바꿉니다.

키 값을 JsonObject에 삽입하기 전에 myString.replace("","\u2024")를 사용하여 키 값을 바꿉니다.

처음에 저는 모든 "." 문자를 유니코드에 해당하는 문자로 바꾸기 위해 간단한 재귀를 사용했지만, 값의 점조차도 교체되고 있다는 것을 알게 되었습니다.그래서 저는 "instance(instance, input, 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

저는 사전을 일련화하거나 문제가 되는 점이 키 이름으로 나타날 수 있는 경우에만 이 문제를 발견했습니다.참조를 표시하도록 편집되었습니다.

빠르고 더러운 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>();
}

언급URL : https://stackoverflow.com/questions/8429318/how-to-use-dot-in-field-name

반응형