我写了一个for循环,它接受一个数据表并使用这个模式创建3,500个对象:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var LocationSchema = new Schema({
twp: {type: String, index: true, unique: true, dropDups: true},
rge: {type: String, unique: true},
});
module.exports = mongoose.model('Location', LocationSchema);
让我们说这是第一个创建的对象:
{
"_id" : ObjectId("56f5eb02683e79de61278449"),
"rge" : "008W",
"twp" : "004S",
"__v" : 0
}
如果使用值twp: 004S
实例化任何其他对象,我希望仍然创建该对象,但是没有twp的值。它看起来像这样:
{
"_id" : ObjectId("56f5eb02683e79de61274949"),
"rge" : "009E",
"__v" : 0
}
正如您所看到的,我尝试添加unique和dropDups,但这仍然创建了具有相同twp
值的多个对象。我还尝试添加以下代码(根据某人的推荐),但结果仍然相同。
var twpSet = new Set();
LocationSchema.methods.twp1 = function () {
var curTwp = this.twp;
if (twpSet.has(curTwp)) {
this.twp = undefined; // remove the twp field once duplicated
} else {
twpSet.add(curTwp); // save the existing twp value
}
};
LocationSchema.queue('twp1');
答案 0 :(得分:0)
问题是因为如果您没有在文档中包含特定字段但该字段上有一个"unique"
索引,那么仍然需要考虑该字段的值为{ {1}}。
引用:
如果文档没有字段值,则该项的索引条目在包含它的任何索引中都将为null。因此,在许多情况下,您需要将唯一约束与稀疏选项组合在一起。稀疏索引会跳过缺少索引字段的任何文档,而不是为索引条目存储null。由于唯一索引不能具有字段的重复值,因此没有稀疏选项,MongoDB将拒绝没有索引字段的第二个文档和所有后续文档。
要解决此问题,请使用创建的索引上的"sparse"
属性。 Heres的演示展示了两种情况:
null
代码注定会出错,但输出会显示会发生什么:
var async = require('async'),
mongoose = require('mongoose'),
Schema = mongoose.Schema;
mongoose.set("debug",true);
mongoose.connect('mongodb://localhost/test');
var sparseSchema = new Schema({
"a": { "type": String, "unique": true, "sparse": true },
"b": { "type": String, "unique": true }
});
var Sparse = mongoose.model('Sparsetest',sparseSchema);
async.eachSeries(
[{ "a": 1, "b": 2 },{ "a": 2 },{ "b": 3 },{ "b": 4 },{ "a": 3 }],
function(item,callback) {
Sparse.create(item,function(err,doc) {
console.log(doc);
callback(err);
});
},
function(err) {
if (err) throw err;
mongoose.disconnect();
}
);
所以创建的前四个文档的一切都很好。第一个文档具有两个属性的唯一值,第二个文档不重复Mongoose: sparsetests.ensureIndex({ a: 1 }) { unique: true, sparse: true, background: true }
Mongoose: sparsetests.insert({ a: '1', b: '2', _id: ObjectId("56f706820c2db3902e557cff"), __v: 0 })
Mongoose: sparsetests.ensureIndex({ b: 1 }) { unique: true, background: true }
{ _id: 56f706820c2db3902e557cff, b: '2', a: '1', __v: 0 }
Mongoose: sparsetests.insert({ a: '2', _id: ObjectId("56f706820c2db3902e557d00"), __v: 0 })
{ _id: 56f706820c2db3902e557d00, a: '2', __v: 0 }
Mongoose: sparsetests.insert({ b: '3', _id: ObjectId("56f706820c2db3902e557d01"), __v: 0 })
{ _id: 56f706820c2db3902e557d01, b: '3', __v: 0 }
Mongoose: sparsetests.insert({ b: '4', _id: ObjectId("56f706820c2db3902e557d02"), __v: 0 })
{ _id: 56f706820c2db3902e557d02, b: '4', __v: 0 }
Mongoose: sparsetests.insert({ a: '3', _id: ObjectId("56f706820c2db3902e557d03"), __v: 0 })
undefined
^
MongoError: E11000 duplicate key error collection: test.sparsetests index: b_1 dup key: { : null }
,第三个文档不重复"a"
。值得注意的是,第三和第四个文档不包含"b"
属性,但由于该属性被"a"
索引,因此这不是问题。
虽然"sparse"
属性不同,但当我们尝试插入另一个文档时,该属性被视为"b"
,则会为该索引抛出重复键错误。即使null
属性仍然是唯一的,"a"
已经有"b"
,所以它不是。{/ p>
因此,如果您想要null
索引,但不打算在每个文档中包含该属性,则必须启用"unique"
。
N.B {@ 1}}选项已被弃用,而且#34; no-op"在任何发布过MongoDB 3.x.无论如何,从集合中删除现有的重复项绝不是一个好的选择。如果您存在重复数据,则需要手动过程将其删除。