【问题标题】:Mongo Giving 'duplicate key error' on non-unique fieldsMongo在非唯一字段上给出“重复键错误”
【发布时间】:2015-04-30 17:57:18
【问题描述】:

尝试插入子文档时出现 MongoDB 错误。子文档已经有唯一的 _id,但是对于我不希望唯一的不同的非唯一字段会引发错误。

Angular 中的错误是:“Assets.serial 已经存在”。 如何使该字段包含重复值,以及是什么导致模型假定它应该是唯一的?

这是我的猫鼬模型:

'use strict';

var mongoose = require('mongoose'),
Schema = mongoose.Schema;
var AssetUrlSchema = new Schema({
  name: {
    type: String,
    unique: false,
    default: '',
    trim: true
  },
  url: {
    type: String,
    unique: false,
    default: 'http://placehold.it/75x75',
    trim: true
  },
}),

AssetSchema = new Schema({
  serial: {
    type: Number,
    unique: false
  },
  urls: {
    type: [AssetUrlSchema],
    unique: false,
    default: [
      { name: '', url: 'http://placehold.it/75x75' },
      { name: '', url: 'http://placehold.it/75x75' }
    ]
  }
}),

/**
 * Item Schema
 */
ItemSchema = new Schema({
    name: {
        type: String,
        default: '',
        required: 'Please enter name',
        trim: true
    },

  assets: {
    type: [AssetSchema],
    default: [],
    unique: false
  },

  property: {
    type: Schema.ObjectId,
    zd: 'Please select a property',
    ref: 'Property'
  },

    created: {
        type: Date,
        default: Date.now
    },

    user: {
        type: Schema.ObjectId,
        ref: 'User'
    }
});

mongoose.model('Item', ItemSchema);

这是我的“保存”方法:

function(){
      var i = 0, assets = [];

      for (;i < 24;i++) {
        assets.push({
          serial: 1000+i,
          urls: {
            name: 'Asset Name ' + i,
            url: 'http://placehold.it/75x75?'
          }
        });
      }

      item = new Items ({
        name: 'FPO',
        property: newPropId,
        assets: assets
      });

      return item.$save(
        function(response){ return response; },
        function(errorResponse) {
          $scope.error = errorResponse.data.message;
        }
      );
    }

我第一次插入文档时,它工作正常。任何后续时间,它都会以 400 失败,因为 assets.serial 字段不是唯一的。但是,我特别将该字段标记为 unique:false。

模式控制台中的错误是:

{ [MongoError: insertDocument :: caused by :: 11000 E11000 duplicate key error index: mean-dev.items.$assets.serial_1  dup key: { : 1000 }]
name: 'MongoError',
code: 11000,
err: 'insertDocument :: caused by :: 11000 E11000 duplicate key error index: mean-dev.items.$assets.serial_1  dup key: { : 1000 }' }
POST /api/items 400 14.347 ms - 41

【问题讨论】:

    标签: angularjs node.js mongodb mongoose


    【解决方案1】:

    Mongoose 不会删除现有索引,因此您需要显式删除索引以摆脱它。在外壳中:

    > db.items.dropIndex('assets.serial_1')
    

    如果您最初定义了该字段 unique: true,但后来将其从架构定义中删除或将其更改为 unique: false,则会发生这种情况。

    【讨论】:

    • 谢谢,这很有帮助,但是是什么使该字段成为索引?它永远不应该是唯一的。
    • @BrandonFitzpatrick 它一定是在过去的某个时候被创建为唯一索引的。它不会是在你删除它并让 Mongoose 使用当前模式定义重新创建它之后。
    • 不确定它是怎么发生的,但是删除索引可以解决它。谢谢!
    • 上帝保佑你儿子!谢谢。
    【解决方案2】:

    如果你使用的是MongoAtlas,你可以去集合->点击'indexes'->在你想删除的索引上,点击'drop index'

    【讨论】:

      【解决方案3】:

      如果您处于开发/原型模式,只需删除实际集合(例如在将 unique:true 更改为 false 之后),将重置所有内容,而 mongoose 将允许您的重复。

      【讨论】:

        猜你喜欢
        • 2015-05-11
        • 2013-06-11
        • 2017-02-03
        • 2015-08-07
        • 1970-01-01
        • 2012-01-06
        • 2022-07-26
        • 2015-07-23
        • 2021-07-10
        相关资源
        最近更新 更多