MongoDB point (.) dans le nom de la clé
Il semble mongo ne permet pas l'insertion de clés avec un point (.) ou le signe dollar ( $ ), cependant quand j'ai importé un fichier JSON contenant un point à l'aide de la mongoimport outil, il a bien fonctionné. Le pilote se plaint d'une tentative d'insertion de cet élément.
C'est ce que le document ressemble dans la base de données:
{
"_id": {
"$oid": "..."
},
"make": "saab",
"models": {
"9.7x": [
2007,
2008,
2009,
2010
]
}
}
Suis-je le faire tout faux et ne doit pas être à l'aide de hachage des cartes avec des données externes (c'est à dire les modèles) ou puis-je échapper à la dot en quelque sorte? Peut-être que je pense trop de Javascript-comme.
- Double Possible de Comment avez-vous stocker les clés dans Mongodb avec un '.' dans eux
- Intéressant de regarder, npmjs.com/package/mongo-escape
Vous devez vous connecter pour publier un commentaire.
MongoDB ne prend pas en charge les touches avec un point en eux de sorte que vous allez avoir à traiter votre fichier JSON pour les supprimer et les remplacer avant de l'importer ou vous serez vous-même la mise en place de toutes sortes de problèmes.
Il n'y a pas un standard solution de contournement à ce problème, la meilleure approche est trop dépendant de la spécificité de la situation. Mais je préfère éviter n'importe quelle touche de l'encodeur/décodeur approche, si possible, que vous allez continuer à payer les inconvénients de ce à perpétuité, où un JSON restructurer l'aurait vraisemblablement d'un coût ponctuel.
.
avec[dot]
? Ou devrais-je restructurer mon JSON en quelque sorte à éviter tout ensemble?models
ici), et (c) nous ne t besoin de les interroger par le nom de la clé à Mongo. Ainsi, un modèle que j'ai réglé sur est deJSON.stringify
ce domaine sur enregistrer, et 'JSON.parse` sur les récupérer.La Mongo docs suggèrent de remplacer des caractères illégaux tels que
$
et.
avec leur unicode équivalents.db.test.insert({"field\uff0ename": "test"})
Comme mentionné dans d'autres réponses MongoDB ne permet pas
$
ou.
caractères d'une map en raison de restrictions sur les noms de champ. Toutefois, comme mentionné dans Signe De Dollar Opérateur De S'Échapper cette restriction ne vous empêche pas de insertion documents avec ces touches, il juste ne vous empêche de mettre à jour ou de l'interrogation eux.Le problème de simplement remplacer
.
avec[dot]
ouU+FF0E
(comme mentionné ailleurs sur cette page), ce qui arrive lorsque l'utilisateur légitimement veut stocker la clé[dot]
ouU+FF0E
?Une approche qui Fantom s afMorphia pilote prend, est d'utiliser les séquences d'échappement unicode similaire à celle de Java, mais bien d'assurer le caractère d'échappement est échappé de la première. En substance, le suivant de la chaîne de remplacement est fait (*):
Un revers de remplacement est faite lorsque les map sont par la suite lire de MongoDB.
Ou dans Fantom code:
La seule fois qu'un utilisateur doit être conscient de ces conversions est lors de la construction de requêtes pour les clés.
Donné, il est courant de stocker
dotted.property.names
dans les bases de données pour la configuration, je crois que cette approche est préférable de simplement l'interdiction de tous ces map.(*) afMorphia effectue réellement complet /bon unicode échapper à des règles comme mentionné dans D'échappement Unicode syntaxe de Java mais le décrit la séquence de remplacement fonctionne tout aussi bien.
//g
pour remplacer toutes les occurrences et pas seulement la première. Aussi, l'utilisation de toute la largeur de la quasi-Martin Konecny la réponse semble être une bonne idée. Enfin, une barre oblique inverse est assez pour le codage.key.replace(/\./g, '\uff0e').replace(/\$/g, '\uff04').replace(/\\/g, '\uff3c')
U+FF04
.Vous pouvez essayer d'utiliser un hachage de la clé au lieu de la valeur, puis stocker cette valeur dans la valeur JSON.
Vous pouvez alors accéder à l'aide de modèles de hachage plus tard.
La dernière version stable (v3.6.1) de la MongoDB prend en charge les points (.) dans les clés ou les noms de champ maintenant.
Les noms de champ peut contenir des points (.) et le dollar ($) caractères maintenant
mongoClient.getDatabase("mydb").getCollection("test").insertOne(new Document("value", new Document("key.with.dots", "value").append("$dollar", "value")));
Il échoue en utilisant mongodb-pilote.3.6.3 et MongoDB 3.6.3.mongodb-4.1.1
etpymongo-3.7.1
. Je peux ajouter des documents contenant des clés avec.
avec robomongo mais pas depymongo
, il sill soulèveInvalidDocument: key '1.1' must not contain '.'
voudrais qu'il avait été fixé par maintenant...Une solution, j'ai juste mis en place je suis vraiment heureux avec consiste à fendre le nom de la clé et de la valeur dans les deux champs distincts. De cette façon, je peux garder les caractères exactement le même, et pas à vous soucier de ceux analyse des cauchemars. Le doc ressemblerait à:
Vous pouvez toujours demander à ce assez facile, juste à faire un
find
sur les champs keyName et keyValue.Ainsi, au lieu de:
qui ne fait pas travailler comme prévu, vous devez exécuter:
et il sera de retour prévu le document.
De la MongoDB docs "le caractère '.' ne doit pas apparaître n'importe où dans le nom de la clé". Il semble que vous aurez à venir avec un schéma de codage ou de faire sans.
Vous aurez besoin pour échapper à la clés. Depuis il semble que la plupart des gens ne savent pas comment échapper à cordes, voici les étapes:
Aussi, n'oubliez pas que mongo n'autorisons pas les clés de commencer par '$', de sorte que vous avez à faire quelque chose de similaire il y
Voici un code qui le fait:
Une réponse tardive, mais si vous utilisez du Printemps et de Mongo, le Printemps peut gérer la conversion pour vous avec
MappingMongoConverter
. C'est la solution par JohnnyHK mais géré par Spring.Si votre stockées Json est :
Par le Ressort (MongoClient), il sera lu comme suit :
J'utilise la suite s'échapper en JavaScript pour chaque objet clé:
Ce que j'aime c'est qu'il remplace seulement
$
au début, et il n'utilise pas de caractères unicode qui peut être difficile à utiliser dans la console._
est pour moi beaucoup plus lisible qu'un caractère unicode. Il ne remplace pas un jeu de caractères spéciaux ($
,.
) à un autre (unicode). Mais bien s'échappe avec traditionnel\
.Pas parfait, mais il fonctionne dans la plupart des situations: remplacer les caractères interdits par quelque chose d'autre. Puisque c'est dans les touches, ces caractères doivent être assez rares.
Voici un test:
et les résultats de noter que les valeurs ne sont pas modifiées:
Pour PHP-je remplacer la valeur HTML pour la période. C'est
"."
.Il stocke dans MongoDB comme ceci:
et le code PHP...
Lodash paires vous permettra de changer
en
à l'aide de
Vous pouvez les stocker et de les convertir à peu après
J'ai écrit cet exemple sur Livescript. Vous pouvez utiliser livescript.net site web de eval il
Il va produire
JS:
Vous donner mon astuce: Vous pouvez à l'aide de JSON.stringify pour économiser de l'Objet/Tableau contient le nom de la clé a points, ensuite d'analyser la chaîne de l'Objet JSON.analyser à traiter lorsque des données de la base de données
Une autre solution de contournement:
Restructurer votre schéma comme:
Dernière MongoDB prend en charge les touches avec un point, mais java MongoDB-pilote n'est pas à l'appui. Donc, pour le faire fonctionner en Java, j'ai retiré le code de dépôt github de java-mongo-pilote et a apporté des changements dans leur isValid Touche de fonction, a créé de nouveaux pot dehors, à l'aide maintenant.
Remplacer le point(
.
) ou dollar($
) avec d'autres personnages qui ne sera jamais utilisé dans le vrai document. Et de restauration de la dot(.
) ou dollar($
) lors de la récupération du document. La stratégie n'influencera pas les données que l'utilisateur de lire.Vous pouvez sélectionner le caractère à partir de tous les personnages.
L'étrange c'est, en utilisant mongojs, je peux créer un document avec un point si j'ai mis le _id moi-même, cependant je ne peux pas créer un document lorsque la _id est généré:
Fonctionne:
Ne fonctionne pas:
J'ai d'abord pensé dat mise à jour d'un document avec un point clé a également travaillé, mais son identification de la dot comme une sous-clé de!
De voir comment mongojs poignées de la dot (sous-clé), je vais m'assurer que mes touches ne contient pas de dot.
/home/user/anaconda3/lib/python3.6/site-packages/pymongo/collection.py
Trouvé dans les messages d'erreur. Si vous utilisez
anaconda
(trouver le fichier correspondant dans le cas contraire), il suffit de modifier la valeur decheck_keys = True
àFalse
dans le fichier indiqué ci-dessus. Que ça va marcher!