¿Cómo usar el punto en el nombre del campo?

¿Cómo usar el punto en el nombre del campo?

Veo error en el ejemplo:

db.test2.insert({ "aa" : "b" }) can't have . in field names [aa] 

Puede reemplazar los símbolos de punto de su nombre de campo por el equivalente en Unicode de \uff0E

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

Ver más:

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

De hecho, puede usar puntos en las consultas. Ver: http://www.mongodb.org/display/DOCS/Dot+Notation+%28Reaching+into+Objects%29

Debido a este símbolo de punto especial, significa que no puede usarlo en los nombres de campo. Al igual que no puede usar el símbolo de punto en los identificadores en la mayoría de los lenguajes de progtwigción.

Puede escribir la consulta db.test2.find({ "aa" : "b" }) pero si desea poder escribir una consulta de este tipo, debe insertar su objeto de la siguiente manera: db.test2.insert({"a": {"a": "b"}}) . Esto creará un documento con el campo llamado "a" con el valor del documento incrustado que contiene el campo llamado "a" (nuevamente) con el valor "b" .

También puede escribir un SONManipulator utilizando la biblioteca pymongo que transforma los datos que van y salen de mongodb. Hay desventajas; hay un impacto en el rendimiento (el impacto depende de tu caso de uso) y tienes que transformar tus claves cuando haces búsquedas usando find.

Aquí hay un código con un ejemplo de cómo usarlo en el comentario de la clase KeyTransform:

 from pymongo.son_manipulator import SONManipulator class KeyTransform(SONManipulator): """Transforms keys going to database and restres 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 restre 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 

este método recursivo reemplaza todos los caracteres de punto de las claves de un dict con \ uff0E como lo sugiere Fisk

Reemplacé el valor de la clave usando myString.replace (“.”, “\ U2024”) antes de insertarlo en JsonObject.

Inicialmente utilicé una recursión simple para reemplazar todo “.” caracteres con su equivalente unicode, pero se dio cuenta de que incluso los puntos en los valores estaban siendo reemplazados. Así que pensé que deberíamos reemplazar los puntos solo de las claves e hicimos los cambios como corresponda en caso de que “if isinstance (input, dict)”. Pensé que debería ser una condición suficiente para hacer la magia pero olvidé que el valor dict también puede ser un dict o una lista y luego finalmente agregué ese control que si el valor de un dict no era una cuerda, entra recursivamente y finalmente capaz de llegar a esta solución que finalmente hizo el truco.

 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 

Solo me he encontrado con este problema al tratar de serializar Diccionarios y sitios donde el punto ofensivo puede aparecer como un nombre clave. Editado para mostrar las referencias.

El enfoque rápido y sucio de C #:

 using MongoDB.Bson; using Newtonsoft.Json.Linq; using System.Text.RegularExpressions; public static T Sanitize(T obj) { var str = JObject.FromObject(obj).ToJson(); var parsed = Regex.Replace(str, @"\.(?=[^""]*"":)", "_"); //ie 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(); }