web-dev-qa-db-fra.com

MongoDB show duplicate key is null?

MongoDB version 3.6

J'ai reçu le message clé en double lorsque j'ai exécuté cela. Quel est le vrai problème?

mongos> db.setup.findAndModify({
... query : {"_id" : ObjectId("5b3c7abbea95705803084cad")},
... update : {$set : { "test" : "xxxx" }},
... upsert : true
... })
2018-07-06T10:13:22.749+0000 E QUERY    [thread1] Error: findAndModifyFailed failed: {
    "ok" : 0,
    "errmsg" : "E11000 duplicate key error collection: testdb.setup index: name dup key: { : null }",
    "code" : 11000,
    "codeName" : "DuplicateKey",
    "$clusterTime" : {
        "clusterTime" : Timestamp(1530872002, 603),
        "signature" : {
            "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
            "keyId" : NumberLong(0)
        }
    },
    "operationTime" : Timestamp(1530872002, 602)
} :
_getErrorWithCode@src/mongo/Shell/utils.js:25:13
DBCollection.prototype.findAndModify@src/mongo/Shell/collection.js:724:1
@(Shell):1:1
mongos>
4
tao hiko

C'est le cas attendu si vous avez défini un index unique qui n'est pas rare: documents il manque une valeur pour le champ avec l'index unique aura une valeur indexée de null. Cela signifie qu'un seul document de la collection peut ne pas contenir le champ unique.

Le message de clé en double comprend le nom d'index et la violation de clé:

"errmsg": "Collecte des erreurs de clé en double E11000: index testdb.setup: nom clé dup: {: null}",

Dans votre exemple, la collection setup dans la base de données testdb a un index unique dans le champ name. La tentative d'insertion a échoué car le champ name était manquant et il y avait déjà un document dans cette collection avec une valeur manquante ou null pour name.

Si vous souhaitez utiliser un index unique sans que le champ soit présent, vous avez quelques options:

  • Supprimez et recréez l'index unique avec la propriété sparse:

    db.setup.createIndex(
        {name: 1},
        {unique:true, sparse:true}
    )
    
  • Supprimez et recréez l'index unique à l'aide d'un expression de filtre partiel (qui permet d'autres critères si nécessaire):

    db.setup.createIndex(
       { name: 1},
       { unique:true, partialFilterExpression: {name: {$exists:true }}}
    )
    
5
Stennie

J'ai trouvé que d'autres index sur cette collection ont été définis comme "uniques" pour être "vrais" (exclure _id), puis il affiche une erreur.

1
tao hiko