MongoDB-Punkt (.) Im Schlüsselnamen

92

Es scheint, dass Mongo das Einfügen von Schlüsseln mit einem Punkt (.) Oder einem Dollarzeichen ($) nicht zulässt. Als ich jedoch eine JSON-Datei importierte, die einen Punkt enthielt, funktionierte dies mit dem Mongoimport-Tool einwandfrei. Der Treiber beschwert sich über den Versuch, dieses Element einzufügen.

So sieht das Dokument in der Datenbank aus:

{
    "_id": {
        "$oid": "..."
    },
    "make": "saab",
    "models": {
        "9.7x": [
            2007,
            2008,
            2009,
            2010
        ]
    }
}

Mache ich das alles falsch und sollte solche Hash-Maps nicht mit externen Daten (dh den Modellen) verwenden oder kann ich dem Punkt irgendwie entkommen? Vielleicht denke ich zu viel Javascript-ähnlich.

Michael Yagudaev
quelle
Sehenswert, npmjs.com/package/mongo-escape
Sam Denty

Antworten:

81

MongoDB unterstützt keine Schlüssel mit einem Punkt darin, daher müssen Sie Ihre JSON-Datei vorverarbeiten, um sie vor dem Import zu entfernen / ersetzen, oder Sie müssen sich auf alle möglichen Probleme einstellen.

Es gibt keine Standardumgehung für dieses Problem. Der beste Ansatz hängt zu stark von den Besonderheiten der Situation ab. Ich würde jedoch nach Möglichkeit jeden Key-Encoder / Decoder-Ansatz vermeiden, da Sie die Unannehmlichkeiten weiterhin auf Dauer bezahlen werden, wenn eine JSON-Umstrukturierung vermutlich einmalige Kosten verursachen würde.

JohnnyHK
quelle
1
Ich glaube nicht, dass es einen Standardweg gibt, der beste Ansatz hängt zu stark von den Besonderheiten der Situation ab. Ich würde jedoch nach Möglichkeit jeden Key-Encoder / Decoder-Ansatz vermeiden, da Sie die Unannehmlichkeiten weiterhin auf Dauer bezahlen werden, wenn eine JSON-Umstrukturierung vermutlich einmalige Kosten verursachen würde.
JohnnyHK
8
Bin wieder in diese Situation geraten. Dies scheint nicht so sehr bei App-Schlüsselnamen der Fall zu sein, die wir steuern können und häufig abfragen müssen, sondern bei vom Benutzer bereitgestellten Daten in verschachtelten Datenstrukturen, die wir nicht steuern können, aber (a) in Mongo speichern möchten , (b) wir wissen, in welchen spezifischen Feldern dies passieren kann (z. B. modelshier), und (c) wir müssen sie nicht nach dem Schlüsselnamen in Mongo abfragen. Ein Muster, für das ich mich entschieden habe, ist JSON.stringifydieses Feld beim Speichern und 'JSON.parse' beim Abrufen.
Prototyp
15
Wenn Sie müssen, können Sie die Option {check_keys: false} angeben, um dieses Problem zu umgehen.
Tzury Bar Yochay
5
@TzuryBarYochay OMG Sie haben das MongoDB-Äquivalent der Nordwestpassage gefunden. Ich denke, das sollte die akzeptierte Antwort sein.
Prototyp
2
@emarel db.collection_foo.update ({this: "that"}, {$ set: {a: "b"}}, {check_keys: false})
Tzury Bar Yochay
21

Wie in anderen Antworten erwähnt MongoDB nicht erlaubt $oder .Zeichen als Mapkeys wegen Beschränkungen für Feldnamen . Wie in Dollar Sign Operator erwähnt. Wenn Sie dieser Einschränkung jedoch entkommen, können Sie keine Dokumente mit solchen Schlüsseln einfügen , sondern sie nur aktualisieren oder abfragen.

Das Problem beim einfachen Ersetzen .durch [dot]oder U+FF0E(wie an anderer Stelle auf dieser Seite erwähnt) ist, was passiert, wenn der Benutzer den Schlüssel rechtmäßig speichern möchte [dot]oder U+FF0E?

Ein Ansatz, den der afMorphia-Treiber von Fantom verfolgt , besteht darin, Unicode-Escape-Sequenzen zu verwenden, die denen von Java ähnlich sind, aber sicherzustellen, dass das Escape-Zeichen zuerst maskiert wird. Im Wesentlichen werden die folgenden Zeichenfolgen ersetzt (*):

\  -->  \\
$  -->  \u0024
.  -->  \u002e

Ein umgekehrter Austausch erfolgt, wenn die Kartenschlüssel anschließend aus MongoDB gelesen werden .

Oder im Fantomcode :

Str encodeKey(Str key) {
    return key.replace("\\", "\\\\").replace("\$", "\\u0024").replace(".", "\\u002e")
}

Str decodeKey(Str key) {
    return key.replace("\\u002e", ".").replace("\\u0024", "\$").replace("\\\\", "\\")
}

Ein Benutzer muss sich solcher Konvertierungen nur bewusst sein, wenn er Abfragen für solche Schlüssel erstellt.

Da es üblich ist, zu dotted.property.namesKonfigurationszwecken in Datenbanken zu speichern , ist dieser Ansatz meines Erachtens dem einfachen Verbot aller dieser Kartenschlüssel vorzuziehen.

(*) afMorphia führt tatsächlich vollständige / ordnungsgemäße Unicode-Escape- Regeln aus, wie in der Unicode-Escape-Syntax in Java erwähnt, aber die beschriebene Ersetzungssequenz funktioniert genauso gut.

Steve Eynon
quelle
Sollte verwendet werden //g, um alle Vorkommen zu ersetzen und nicht nur das erste. Auch die Verwendung der Äquivalente in voller Breite wie in Martin Konecnys Antwort scheint eine gute Idee zu sein. Schließlich reicht ein Backslash für die Codierung aus. key.replace(/\./g, '\uff0e').replace(/\$/g, '\uff04').replace(/\\/g, '\uff3c')
cw '
1
@cw '- Der Code hat eine Java-ähnliche Syntax. Ersetzen ersetzt also tatsächlich alle Vorkommen, und doppelte Backslashes sind erforderlich, um Backslashes zu vermeiden. Und wieder müssen Sie eine Form der Flucht einführen, um sicherzustellen, dass alle Fälle abgedeckt sind. Jemand möchte irgendwann tatsächlich einen Schlüssel von U+FF04.
Steve Eynon
2
Wie sich herausstellt, unterstützt Mongodb Punkte und Dollars in seinen neuesten Versionen. Siehe: - stackoverflow.com/a/57106679/3515086
Abhidemon
18

In den Mongo-Dokumenten wird vorgeschlagen , illegale Zeichen wie $und .durch ihre Unicode-Entsprechungen zu ersetzen .

In diesen Situationen müssen die Schlüssel die reservierten $ und ersetzen. Zeichen. Jedes Zeichen ist ausreichend, aber verwenden Sie die Unicode-Äquivalente in voller Breite: U + FF04 (dh „$“) und U + FF0E (dh „.“).

Martin Konecny
quelle
72
Das klingt nach einem Rezept für massives Debuggen von Kopfschmerzen.
niemand
2
@ AndrewMedico, @ Tamlyn - Ich denke, die Dokumente bedeuten so etwas wiedb.test.insert({"field\uff0ename": "test"})
P. Myer Nore
4
-1 A. Das ist eine schreckliche Idee - was ist, wenn jemand tatsächlich versucht, diese Unicode-Zeichen als Schlüssel zu verwenden? Dann haben Sie einen stillen Fehler, der bewirkt, wer was mit Ihrem System weiß. Verwenden Sie solche mehrdeutigen Escape-Methoden nicht. B. die Mongo-Dokumente sagen das nicht mehr, wahrscheinlich weil jemand erkannt hat, dass es eine schreckliche Idee ist
BT
7
@SergioTulentsev Ich habe sie dazu gebracht, die Empfehlung zu entfernen :) github.com/mongodb/docs/commit/…
BT
2
@ BT: Hut Tipp an Sie, Sir :)
Sergio Tulentsev
15

Die neueste stabile Version (v3.6.1) der MongoDB unterstützt jetzt Punkte (.) In den Schlüsseln oder Feldnamen.

Feldnamen können jetzt Punkte (.) Und Dollarzeichen ($) enthalten

h4ck3d
quelle
10
Selbst wenn der Server dies jetzt unterstützt, sucht der Treiber immer noch nach $ und Punkten in Schlüsseln und akzeptiert diese nicht. Daher unterstützt Mongo theoretisch nur Punkte und Dollarzeichen. Praktisch ist dies noch nicht verwendbar :(
JMax
Möglicherweise verwenden Sie einen alten oder inkompatiblen Client. Ich habe dies auf meinen Produktionsservern ohne Schweiß verwendet. Ich habe nach NodeJS- und Java-Clients gesucht.
h4ck3d
Mit Java funktioniert es definitiv nicht! Versuchen Sie den folgenden Befehl: mongoClient.getDatabase("mydb").getCollection("test").insertOne(new Document("value", new Document("key.with.dots", "value").append("$dollar", "value")));Die Verwendung von mongodb-driver.3.6.3 und MongoDB 3.6.3 schlägt fehl.
JMax
1
In der Tat habe ich es gerade mit einem Setup versucht mongodb-4.1.1und pymongo-3.7.1. Ich kann Dokumente mit Schlüsseln mit .Robomongo hinzufügen, aber nicht mit pymongo, es wird immer noch ausgelöst. InvalidDocument: key '1.1' must not contain '.'Ich wünschte, es wäre inzwischen behoben worden ...
Lernen ist ein Chaos
Ich habe es mit Mongodb Server 4.0.9 und Java-Treiber 3.10.2 versucht, aber es akzeptiert keinen Punkt im Schlüsselnamen. Es ist seltsam, dass es funktioniert, wenn man versucht, Robomongo zu verwenden ...
xyzt
12

Eine Lösung, mit der ich gerade zufrieden bin, besteht darin, den Schlüsselnamen und den Wert in zwei separate Felder aufzuteilen. Auf diese Weise kann ich die Charaktere exakt gleich halten und mir keine Sorgen über diese Alpträume machen. Das Dokument würde folgendermaßen aussehen:

{
    ...
    keyName: "domain.com",
    keyValue: "unregistered",
    ...
}

Sie können dies immer noch einfach genug abfragen, indem Sie findin den Feldern keyName und keyValue einen Wert eingeben .

Also statt:

 db.collection.find({"domain.com":"unregistered"})

was nicht wirklich wie erwartet funktionieren würde, würden Sie ausführen:

db.collection.find({keyName:"domain.com", keyValue:"unregistered"})

und es wird das erwartete Dokument zurückgeben.

Steve
quelle
Wie du das gemacht hast? Könnten Sie mir bitte in diesem Fall helfen?
Profiler
Ich habe ein Abfragebeispiel hinzugefügt. Hilft das?
Steve
10

Sie können versuchen, anstelle des Werts einen Hash im Schlüssel zu verwenden und diesen Wert dann im JSON-Wert zu speichern.

var crypto = require("crypto");   

function md5(value) {
    return crypto.createHash('md5').update( String(value) ).digest('hex');
}

var data = {
    "_id": {
        "$oid": "..."
    },
    "make": "saab",
    "models": {}
}

var version = "9.7x";

data.models[ md5(version) ] = {
    "version": version,
    "years" : [
        2007,
        2008,
        2009,
        2010
    ]
}

Sie würden dann später mit dem Hash auf die Modelle zugreifen.

var version = "9.7x";
collection.find( { _id : ...}, function(e, data ) {
    var models = data.models[ md5(version) ];
}
Henry
quelle
1
Ich mag diese saubere Lösung mit 1-Wege-Hashing und sehr ähnlich wie die Dinge unter der Haube funktionieren.
Michael Yagudaev
3
Das Problem bei der Verwendung von Hashes als Schlüssel besteht darin, dass nicht garantiert wird, dass sie eindeutig sind, und dass sie häufig Kollisionen verursachen . Außerdem scheint es mir nicht die optimale Lösung zu sein, jedes Mal, wenn Sie auf eine Karte zugreifen möchten, einen kryptografischen Hash zu berechnen.
Steve Eynon
2
Warum ist dies besser, als den Punkt durch ein Sonderzeichen oder eine Sonderfolge zu ersetzen?
B Sieben
Das Konvertieren von Strings in base64 ist viel besser.
Zen
8

Es wird jetzt unterstützt

Ab MongoDb 3.6 werden sowohl Punkte als auch Dollar in Feldnamen unterstützt. Siehe unten JIRA: https://jira.mongodb.org/browse/JAVA-2810

Ein Upgrade Ihres Mongodb auf 3.6+ klingt nach dem besten Weg.

Abhidemon
quelle
Dies ist die beste Antwort hier. : +1
hallo_abhishek
2
3.6 kann sie speichern, ja, aber es wird noch nicht unterstützt, kann Treiberfehler auslösen und Abfragen / Aktualisierungen unterbrechen : Einschränkungen : "Die MongoDB-Abfragesprache kann Abfragen über Dokumente, deren Feldnamen diese Zeichen enthalten, nicht immer sinnvoll ausdrücken (siehe SERVER-). 30575). Bis zur Unterstützung in der Abfragesprache wird die Verwendung von $ und. In Feldnamen nicht empfohlen und von den offiziellen MongoDB-Treibern nicht unterstützt . "
JeremyDouglass
4

Aus den MongoDB-Dokumenten "the '." Zeichen darf nirgendwo im Schlüsselnamen erscheinen ". Es sieht so aus, als müssten Sie sich ein Kodierungsschema einfallen lassen oder darauf verzichten.

Maerics
quelle
4

Sie müssen den Schlüsseln entkommen. Da es den Anschein hat, dass die meisten Menschen nicht wissen, wie sie Strings richtig entkommen können, sind hier die Schritte:

  1. Wählen Sie einen Escape-Charakter (am besten einen Charakter, der selten verwendet wird). Z.B. '~'
  2. Um zu entkommen, ersetzen Sie zuerst alle Instanzen des Escape-Zeichens durch eine Sequenz, der Ihr Escape-Zeichen vorangestellt ist (z. B. '~' -> '~ t'), und ersetzen Sie dann das Zeichen oder die Sequenz, die Sie zum Escape benötigen, durch eine Sequenz, der Ihr Escape-Zeichen vorangestellt ist . Z.B. '.' -> '~ p'
  3. Um zu entkommen, entfernen Sie zuerst die Escape-Sequenz aus allen Instanzen Ihrer zweiten Escape-Sequenz (z. B. '~ p' -> '.') Und transformieren Sie dann Ihre Escape-Zeichenfolge in ein einzelnes Escape-Zeichen (z. B. '~ s' -> '~ ')

Denken Sie auch daran, dass Mongo auch nicht zulässt, dass Schlüssel mit '$' beginnen, sodass Sie dort etwas Ähnliches tun müssen

Hier ist ein Code, der das macht:

// returns an escaped mongo key
exports.escape = function(key) {
  return key.replace(/~/g, '~s')
            .replace(/\./g, '~p')
            .replace(/^\$/g, '~d')
}

// returns an unescaped mongo key
exports.unescape = function(escapedKey) {
  return escapedKey.replace(/^~d/g, '$')
                   .replace(/~p/g, '.')
                   .replace(/~s/g, '~')
}
BT
quelle
Diese Flucht kann immer noch brechen, wenn Sie Zeichenfolgen wie '. ~ P.' Haben. Hier ist die maskierte Zeichenfolge '~ p ~~ p ~ p'. Wenn Sie sich entziehen, erhalten Sie '. ~ ..', was sich von der tatsächlichen Zeichenfolge unterscheidet.
JVC
1
@jvc Du hast recht! Ich habe die Erklärungs- und Beispiel-Escape-Funktionen behoben. Lass es mich wissen, wenn sie noch kaputt sind!
BT
3

Eine späte Antwort, aber wenn Sie Spring und Mongo verwenden, kann Spring die Konvertierung für Sie verwalten MappingMongoConverter. Es ist die Lösung von JohnnyHK, wird aber von Spring gehandhabt.

@Autowired
private MappingMongoConverter converter;

@PostConstruct
public void configureMongo() {
 converter.setMapKeyDotReplacement("xxx");
}

Wenn Ihr gespeicherter Json ist:

{ "axxxb" : "value" }

Durch den Frühling (MongoClient) wird es gelesen als:

{ "a.b" : "value" }
Bommel
quelle
erforderte eine Bean vom Typ 'org.springframework.data.mongodb.core.convert.MappingMongoConverter', die nicht gefunden werden konnte.
Sathya Narayan C
1

Ich verwende das folgende Escapezeichen in JavaScript für jeden Objektschlüssel:

key.replace(/\\/g, '\\\\').replace(/^\$/, '\\$').replace(/\./g, '\\_')

Was ich daran mag, ist, dass es nur $am Anfang ersetzt wird und keine Unicode-Zeichen verwendet, deren Verwendung in der Konsole schwierig sein kann. _ist für mich viel lesbarer als ein Unicode-Zeichen. Es ersetzt auch nicht einen Satz von Sonderzeichen ( $, .) durch einen anderen (Unicode). Aber richtig entkommt mit traditionellen \.

Mitar
quelle
3
Und wenn jemand ein _ in einem seiner Schlüssel verwendet, werden Sie Fehler bekommen.
BT
1

Nicht perfekt, funktioniert aber in den meisten Situationen: Ersetzen Sie die verbotenen Zeichen durch etwas anderes. Da es sich um Schlüssel handelt, sollten diese neuen Zeichen ziemlich selten sein.

/** This will replace \ with ⍀, ^$ with '₴' and dots with ⋅  to make the object compatible for mongoDB insert. 
Caveats:
    1. If you have any of ⍀, ₴ or ⋅ in your original documents, they will be converted to \$.upon decoding. 
    2. Recursive structures are always an issue. A cheap way to prevent a stack overflow is by limiting the number of levels. The default max level is 10.
 */
encodeMongoObj = function(o, level = 10) {
    var build = {}, key, newKey, value
    //if (typeof level === "undefined") level = 20     // default level if not provided
    for (key in o) {
        value = o[key]
        if (typeof value === "object") value = (level > 0) ? encodeMongoObj(value, level - 1) : null     // If this is an object, recurse if we can

        newKey = key.replace(/\\/g, '⍀').replace(/^\$/, '₴').replace(/\./g, '⋅')    // replace special chars prohibited in mongo keys
        build[newKey] = value
    }
    return build
}

/** This will decode an object encoded with the above function. We assume the structure is not recursive since it should come from Mongodb */
decodeMongoObj = function(o) {
    var build = {}, key, newKey, value
    for (key in o) {
        value = o[key]
        if (typeof value === "object") value = decodeMongoObj(value)     // If this is an object, recurse
        newKey = key.replace(/⍀/g, '\\').replace(/^₴/, '$').replace(/⋅/g, '.')    // replace special chars prohibited in mongo keys
        build[newKey] = value
    }
    return build
}

Hier ist ein Test:

var nastyObj = {
    "sub.obj" : {"$dollar\\backslash": "$\\.end$"}
}
nastyObj["$you.must.be.kidding"] = nastyObj     // make it recursive

var encoded = encodeMongoObj(nastyObj, 1)
console.log(encoded)
console.log( decodeMongoObj( encoded) )

und die Ergebnisse - beachten Sie, dass die Werte nicht geändert werden:

{
  subobj: {
    dollarbackslash: "$\\.end$"
  },
  youmustbekidding: {
    subobj: null,
    youmustbekidding: null
  }
}
[12:02:47.691] {
  "sub.obj": {
    $dollar\\backslash: "$\\.end$"
  },
  "$you.must.be.kidding": {
    "sub.obj": {},
    "$you.must.be.kidding": {}
  }
}
Nico
quelle
1

Es gibt eine hässliche Möglichkeit, es abzufragen. Es wird nicht empfohlen, es in der Anwendung und nicht für Debug-Zwecke zu verwenden (funktioniert nur bei eingebetteten Objekten):

db.getCollection('mycollection').aggregate([
    {$match: {mymapfield: {$type: "object" }}}, //filter objects with right field type
    {$project: {mymapfield: { $objectToArray: "$mymapfield" }}}, //"unwind" map to array of {k: key, v: value} objects
    {$match: {mymapfield: {k: "my.key.with.dot", v: "myvalue"}}} //query
])
sredni
quelle
1

Wie bereits von einem anderen Benutzer erwähnt, kann das Codieren / Decodieren in Zukunft problematisch werden. Daher ist es wahrscheinlich einfacher, alle Schlüssel mit einem Punkt zu ersetzen. Hier ist eine rekursive Funktion, die ich gemacht habe, um Schlüssel durch '.' Zu ersetzen. Vorkommen:

def mongo_jsonify(dictionary):
    new_dict = {}
    if type(dictionary) is dict:
        for k, v in dictionary.items():
            new_k = k.replace('.', '-')
            if type(v) is dict:
                new_dict[new_k] = mongo_jsonify(v)
            elif type(v) is list:
                new_dict[new_k] = [mongo_jsonify(i) for i in v]
            else:
                new_dict[new_k] = dictionary[k]
        return new_dict
    else:
        return dictionary

if __name__ == '__main__':
    with open('path_to_json', "r") as input_file:
        d = json.load(input_file)
    d = mongo_jsonify(d)
    pprint(d)

Sie können diesen Code ändern, um auch '$' zu ersetzen, da dies ein weiteres Zeichen ist, das Mongo in einem Schlüssel nicht zulässt.

Teddy Haley
quelle
0

Für PHP ersetze ich den HTML-Wert für den Zeitraum. Das ist"." .

Es speichert in MongoDB wie folgt:

  "validations" : {
     "4e25adbb1b0a55400e030000" : {
     "associate" : "true" 
    },
     "4e25adb11b0a55400e010000" : {
       "associate" : "true" 
     } 
   } 

und der PHP-Code ...

  $entry = array('associate' => $associate);         
  $data = array( '$set' => array( 'validations.' . str_replace(".", `"."`, $validation) => $entry ));     
  $newstatus = $collection->update($key, $data, $options);      
JRForbes
quelle
0

Mit Lodash-Paaren können Sie Änderungen vornehmen

{ 'connect.sid': 's:hyeIzKRdD9aucCc5NceYw5zhHN5vpFOp.0OUaA6' }

in

[ [ 'connect.sid',
's:hyeIzKRdD9aucCc5NceYw5zhHN5vpFOp.0OUaA6' ] ]

mit

var newObj = _.pairs(oldObj);
dampfbetrieben
quelle
0

Sie können es so speichern, wie es ist, und danach in hübsch konvertieren

Ich habe dieses Beispiel auf Livescript geschrieben. Sie können die Website livingcript.net verwenden, um sie zu bewerten

test =
  field:
    field1: 1
    field2: 2
    field3: 5
    nested:
      more: 1
      moresdafasdf: 23423
  field3: 3



get-plain = (json, parent)->
  | typeof! json is \Object => json |> obj-to-pairs |> map -> get-plain it.1, [parent,it.0].filter(-> it?).join(\.)
  | _ => key: parent, value: json

test |> get-plain |> flatten |> map (-> [it.key, it.value]) |> pairs-to-obj

Es wird produzieren

{"field.field1":1,
 "field.field2":2,
 "field.field3":5,
 "field.nested.more":1,
 "field.nested.moresdafasdf":23423,
 "field3":3}

Andrey Stehno
quelle
0

Geben Sie meinen Tipp: Sie können JSON.stringify zum Speichern von Object / Array verwenden, das den Schlüsselnamen enthält, der Punkte enthält, und dann die Zeichenfolge mit JSON.parse in Object analysieren, um sie beim Abrufen von Daten aus der Datenbank zu verarbeiten

Eine weitere Problemumgehung: Restrukturieren Sie Ihr Schema wie folgt:

key : {
"keyName": "a.b"
"value": [Array]
}
Mr.Cra
quelle
0

Die neueste MongoDB unterstützt Schlüssel mit einem Punkt, der Java MongoDB-Treiber wird jedoch nicht unterstützt. Damit es in Java funktioniert, habe ich Code aus dem Github-Repo des Java-Mongo-Treibers abgerufen und entsprechende Änderungen an der Funktion isValid Key vorgenommen. Daraus wurde ein neues JAR erstellt, das jetzt verwendet wird.

ANDY MURAY
quelle
0

Ersetzen Sie den Punkt ( .) oder den Dollar ( $) durch andere Zeichen, die im realen Dokument niemals verwendet werden. Stellen Sie beim Abrufen des Dokuments den Punkt ( .) oder den Dollar ( $) wieder her. Die Strategie hat keinen Einfluss auf die vom Benutzer gelesenen Daten.

Sie können das Zeichen aus allen Zeichen auswählen .

Simin Jie
quelle
0

Das Seltsame ist, dass ich mit Mongojs ein Dokument mit einem Punkt erstellen kann, wenn ich die _id selbst setze. Ich kann jedoch kein Dokument erstellen, wenn die _id generiert wird:

Funktioniert:

db.testcollection.save({"_id": "testdocument", "dot.ted.": "value"}, (err, res) => {
    console.log(err, res);
});

Funktioniert nicht:

db.testcollection.save({"dot.ted": "value"}, (err, res) => {
    console.log(err, res);
});

Ich dachte zuerst, dass das Aktualisieren eines Dokuments mit einem Punktschlüssel auch funktioniert, aber es identifiziert den Punkt als Unterschlüssel!

Wenn ich sehe, wie Mongojs mit dem Punkt (Unterschlüssel) umgehen, werde ich sicherstellen, dass meine Schlüssel keinen Punkt enthalten.

Sam
quelle
0

Entfernen Sie wie das, was @JohnnyHK erwähnt hat, Satzzeichen oder '.' von Ihren Schlüsseln, weil es viel größere Probleme verursacht, wenn sich Ihre Daten in einem größeren Datensatz ansammeln. Dies führt zu Problemen, insbesondere wenn Sie Aggregatoperatoren wie $ merge aufrufen, bei denen auf Schlüssel zugegriffen und diese verglichen werden müssen, wodurch ein Fehler ausgelöst wird. Ich habe es auf die harte Tour gelernt, bitte nicht wiederholen für diejenigen, die anfangen.

Yi Xiang Chong
quelle
-2

/home/user/anaconda3/lib/python3.6/site-packages/pymongo/collection.py

Fand es in Fehlermeldungen. Wenn Sie verwenden anaconda(suchen Sie die entsprechende Datei, falls nicht), ändern Sie einfach den Wert von check_keys = Truein Falsein der oben angegebenen Datei. Das wird funktionieren!

Layang
quelle