Node.js 如何忽略对象中其他字段的重复属性?
我编写了一个for循环,它获取一个数据表,并使用此模式创建3500个对象:Node.js 如何忽略对象中其他字段的重复属性?,node.js,mongodb,mongoose,mongodb-query,Node.js,Mongodb,Mongoose,Mongodb Query,我编写了一个for循环,它获取一个数据表,并使用此模式创建3500个对象: 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}, }); mo
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和dropdup,但这仍然创建了具有相同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');
问题在于,如果文档中没有包含特定字段,但该字段上有索引,则出于索引目的,仍然会考虑该字段的值为
null
引文:
如果文档没有字段值,则该项的索引项在包含该字段的任何索引中都将为空。因此,在许多情况下,您将希望将唯一约束与稀疏选项相结合。稀疏索引跳过任何缺少索引字段的文档,而不是为索引项存储null。由于唯一索引的字段不能有重复的值,如果没有稀疏选项,MongoDB将拒绝第二个文档以及没有索引字段的所有后续文档
要解决此问题,请使用已创建索引上的属性。下面是一个演示,展示了这两种情况:
var async=require('async'),
mongoose=require('mongoose'),
Schema=mongoose.Schema;
mongoose.set(“调试”,true);
猫鼬mongodb://localhost/test');
var sparseSchema=新模式({
“a”:{“type”:String,“unique”:true,“sparse”:true},
“b”:{“type”:字符串,“unique”:true}
});
var Sparse=mongoose.model('Sparsetest',sparseSchema);
async.eachSeries(
[{“a”:1,“b”:2},{“a”:2},{“b”:3},{“b”:4},{“a”:3}],
函数(项,回调){
创建(项目、函数(错误、文档){
控制台日志(doc);
回调(err);
});
},
功能(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})
猫鼬:sparsetests.ensureIndex({b:1}){唯一:真,背景:真}
{id:56F70620C2DB3902E557CFF,b:'2',a:'1',u v:0}
Mongoose:sparsetests.insert({a:'2',_id:ObjectId(“56f706820c2d3902e557d00”),__v:0})
{id:56F70620C2DB3902E557D00,a:'2','v:0}
Mongoose:sparsetests.insert({b:'3',_id:ObjectId(“56f706820c2d3902e557d01”),_v:0})
{id:56F70620C2DB3902E557D01,b:'3',uu v:0}
Mongoose:sparsetests.insert({b:'4',_id:ObjectId(“56f706820c2d3902e557d02”),__v:0})
{id:56F70620C2DB3902E557D02,b:'4',uu v:0}
Mongoose:sparsetests.insert({a:'3',_id:ObjectId(“56f706820c2d3902e557d03”),__v:0})
未定义
^
MongoError:E11000重复密钥错误集合:test.sparsetests索引:b_1重复密钥:{:null}
因此,对于创建的前四个文档,一切都很好。第一个文档对这两个属性都有唯一的值,第二个文档不重复“a”
,第三个和第四个文档不重复“b”
。值得注意的是,这里的第三个和第四个文档不包含“a”
属性,但是由于该属性是“稀疏的”
索引的,所以这不是问题
但是“b”
属性的情况并非如此,当我们尝试插入另一个文档,其中该属性被视为null
时,会为该索引抛出重复键错误。即使“a”
属性仍然是唯一的,“b”
已经具有null
,因此它不是唯一的
因此,如果您想要一个“唯一的”
索引,但不打算在每个文档中包含该属性,则必须启用“稀疏”
N.B不推荐使用
“dropDups”
选项,并且在MongoDB 3.x之前的任何版本中都会出现“no op”。无论如何,从集合中删除现有副本从来都不是一个好的选择。如果存在重复数据,则需要手动过程将其删除。因此,为了实现这一点,我所要做的就是将sparse:true
添加到我的模式中?我试过了,但不太管用。试图在谷歌上搜索更多关于稀疏信息的信息。@fresh5447不仅有相关信息的超链接(和引文),而且还有一个工作示例向您说明错误所在。所以你不可能很努力的。再仔细阅读一遍,看看你的代码哪里出了问题。如果希望从任何文档中“省略”它的字段是唯一的,则该字段需要有稀疏的。否则它是重复的null
。可能是重复的?也许更新原始问题比在SO中给出另一个相同的问题更好?