Mongoose 需要创建 object,但如果另一个 object 已经有这个 属性,则跳过 属性
Mongoose needs to create objects, but skip the property if another object already has this property
我知道标题令人困惑,但让我解释得更清楚。
这是我的猫鼬模式:
var LocationSchema = new Schema({
locationKey: {type: String, unique: true},
wheat: Array,
barley: Array,
cty: {type: String, unique: true},
twp: {type: String, index: { unique: true} , dropDups: true},
rge: {type: String, unique: true},
});
我编写了一些代码,将使用此架构创建 3500 个位置。问题是许多位置的 twp
具有相同的值。在这种情况下,我需要它来创建 object,但如果已创建的任何其他 object 具有相同的 twp
,则不创建 twp
。
正如您在上面看到的,我尝试使用上面的独特方法。为了更清楚起见,这里有两个示例 object:
Object一个:
{
"_id" : ObjectId("56f5af9547a341720b0b25cd"),
"rge" : "034E",
"twp" : "001N",
"cty" : "003",
"locationKey" : "003001N034E",
"__v" : 0
}
如果我要创建一个新的 object,它有 twp: 001N
,我希望创建它,但看起来像这样:
{
"_id" : ObjectId("56f5af9547a341720b0b25cd"),
"rge" : "034W",
"cty" : "004",
"locationKey" : "003001N034E",
"__v" : 0
}
在服务器 JS 中,我有一个包含 3,000 个 object 的数组,我正在遍历这个数组来为每个项目创建一个位置 Object,如下所示:
locations.forEach(function(item){
var location = new Location();
location.locationKey = item.locationKey.trim();
location.cty = item.cty.trim();
location.twp = item.twp.trim();
location.rge = item.rge.trim();
location.wheat = item.wheat;
location.barley = item.barley;
location.save();
});
要添加预创建模式的方法,您可以通过 schema.queue
根据此 discussion 来完成,这里是 mongoose v4.4.6
下的测试代码
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');
测试数据
var l1 = new Loca({
locationKey: 'k1',
cty: 'c1',
twp: 't1',
rge: 'r1'
});
console.log(l1);
l1.save(function(err) {
if (err)
console.log(err);
else
console.log('save location1 successfully');
})
var l2 = new Loca({
locationKey: 'k2',
cty: 'c2',
twp: 't1',
rge: 'r2'
});
console.log(l2);
l2.save(function(err) {
if (err)
console.log(err);
else
console.log('save location2 successfully');
})
结果是
{ "_id" : ObjectId("56f5e484a22885dd0362a39a"), "locationKey" : "k1", "cty" : "c1", "twp" : "t1", "rge" : "r1", "barley" : [ ], "wheat" : [ ], "__v" : 0 }
{ "_id" : ObjectId("56f5e484a22885dd0362a39b"), "locationKey" : "k2", "cty" : "c2", "rge" : "r2", "barley" : [ ], "wheat" : [ ], "__v" : 0 }
另一种选择是通过.pre('save'
中间件检查save
新文档之前的现有文档,如果找到重复的twp
,则在新文档中将其删除,然后保存.
LocationSchema.pre('save', function(next) {
var curTwp = this.twp;
console.log(curTwp);
var obj = this;
Loca.findOne({twp: curTwp}, function(err, loc) {
if (err)
next(err);
else if (loc) {
// find the duplicate twp before save
obj.twp = undefined;
next();
}else
next();
})
});
var Loca = mongoose.model('Loca', LocationSchema);
测试代码
var l1 = new Loca({
locationKey: 'k1',
cty: 'c1',
twp: 't1',
rge: 'r1'
});
var l2 = new Loca({
locationKey: 'k2',
cty: 'c2',
twp: 't1',
rge: 'r2'
});
console.log(l1);
l1.save(function(err) {
if (err)
console.log(err);
else {
l2.save(function(err) {
if (err)
console.log(err);
else
console.log('save location2 successfully');
})
}
})
如上保存结果,为了确保你的海量数据被一一保存,你可以使用async.series
.
我知道标题令人困惑,但让我解释得更清楚。
这是我的猫鼬模式:
var LocationSchema = new Schema({
locationKey: {type: String, unique: true},
wheat: Array,
barley: Array,
cty: {type: String, unique: true},
twp: {type: String, index: { unique: true} , dropDups: true},
rge: {type: String, unique: true},
});
我编写了一些代码,将使用此架构创建 3500 个位置。问题是许多位置的 twp
具有相同的值。在这种情况下,我需要它来创建 object,但如果已创建的任何其他 object 具有相同的 twp
,则不创建 twp
。
正如您在上面看到的,我尝试使用上面的独特方法。为了更清楚起见,这里有两个示例 object:
Object一个:
{
"_id" : ObjectId("56f5af9547a341720b0b25cd"),
"rge" : "034E",
"twp" : "001N",
"cty" : "003",
"locationKey" : "003001N034E",
"__v" : 0
}
如果我要创建一个新的 object,它有 twp: 001N
,我希望创建它,但看起来像这样:
{
"_id" : ObjectId("56f5af9547a341720b0b25cd"),
"rge" : "034W",
"cty" : "004",
"locationKey" : "003001N034E",
"__v" : 0
}
在服务器 JS 中,我有一个包含 3,000 个 object 的数组,我正在遍历这个数组来为每个项目创建一个位置 Object,如下所示:
locations.forEach(function(item){
var location = new Location();
location.locationKey = item.locationKey.trim();
location.cty = item.cty.trim();
location.twp = item.twp.trim();
location.rge = item.rge.trim();
location.wheat = item.wheat;
location.barley = item.barley;
location.save();
});
要添加预创建模式的方法,您可以通过 schema.queue
根据此 discussion 来完成,这里是 mongoose v4.4.6
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');
测试数据
var l1 = new Loca({
locationKey: 'k1',
cty: 'c1',
twp: 't1',
rge: 'r1'
});
console.log(l1);
l1.save(function(err) {
if (err)
console.log(err);
else
console.log('save location1 successfully');
})
var l2 = new Loca({
locationKey: 'k2',
cty: 'c2',
twp: 't1',
rge: 'r2'
});
console.log(l2);
l2.save(function(err) {
if (err)
console.log(err);
else
console.log('save location2 successfully');
})
结果是
{ "_id" : ObjectId("56f5e484a22885dd0362a39a"), "locationKey" : "k1", "cty" : "c1", "twp" : "t1", "rge" : "r1", "barley" : [ ], "wheat" : [ ], "__v" : 0 }
{ "_id" : ObjectId("56f5e484a22885dd0362a39b"), "locationKey" : "k2", "cty" : "c2", "rge" : "r2", "barley" : [ ], "wheat" : [ ], "__v" : 0 }
另一种选择是通过.pre('save'
中间件检查save
新文档之前的现有文档,如果找到重复的twp
,则在新文档中将其删除,然后保存.
LocationSchema.pre('save', function(next) {
var curTwp = this.twp;
console.log(curTwp);
var obj = this;
Loca.findOne({twp: curTwp}, function(err, loc) {
if (err)
next(err);
else if (loc) {
// find the duplicate twp before save
obj.twp = undefined;
next();
}else
next();
})
});
var Loca = mongoose.model('Loca', LocationSchema);
测试代码
var l1 = new Loca({
locationKey: 'k1',
cty: 'c1',
twp: 't1',
rge: 'r1'
});
var l2 = new Loca({
locationKey: 'k2',
cty: 'c2',
twp: 't1',
rge: 'r2'
});
console.log(l1);
l1.save(function(err) {
if (err)
console.log(err);
else {
l2.save(function(err) {
if (err)
console.log(err);
else
console.log('save location2 successfully');
})
}
})
如上保存结果,为了确保你的海量数据被一一保存,你可以使用async.series
.