Mongoose需要创建对象,但如果另一个对象已经具有此属性,则跳过该属性

时间:2016-03-26 00:08:54

标签: node.js mongodb mongoose mongoose-schema

我知道标题令人困惑,但让我更清楚地解释一下。

以下是我的mongoose架构:

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具有相同的价值。在这种情况下,我需要它仍然创建对象,但如果已创建的任何其他对象具有相同的twp,则不需要创建twp

正如您在上面所看到的,我尝试使用上面的独特方法。为了更加清晰,这里有两个示例对象:

对象一:

{
    "_id" : ObjectId("56f5af9547a341720b0b25cd"),
    "rge" : "034E",
    "twp" : "001N",
    "cty" : "003",
    "locationKey" : "003001N034E",
    "__v" : 0
}

如果我要创建一个具有twp: 001N的新对象,我希望它被创建,但看起来像这样:

{
    "_id" : ObjectId("56f5af9547a341720b0b25cd"),
    "rge" : "034W",
    "cty" : "004",
    "locationKey" : "003001N034E",
    "__v" : 0
}

在服务器JS中,我有一个包含3,000个对象的数组,我循环遍历此数组,为每个项目创建一个位置对象,如下所示:

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();
});

1 个答案:

答案 0 :(得分:1)

要添加预创建架构的方法,您可以通过schema.queuediscussion执行此操作,以下是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 }

另一种选择是通过save中间件在.pre('save'新文档之前检查现有文档,如果找到重复的twp,则在新文档中将其删除,然后保存。< / p>

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