Mongoose使用catergorized子文档创建一个新文档

时间:2016-03-13 02:07:01

标签: javascript node.js mongodb mongoose mean-stack

我一直在浏览Mongoose文档,我认为我对它的工作方式缺乏一些基本的了解。

我正在尝试做什么

我正在进行第三方API调用,返回看起来像

的结构
Route
 |__Train 1 on Route
     |__Upcoming Station (with ID)
     |   |__Time to this station
     |__Upcoming Station (with ID)
     |   |__Time to this station
     ...
 |__Train 2
        ...

我的目标是将其格式化为文档

tableId : String,

stations : [{   
    stopId : String, 
    incoming : [{
        vehicleId : String,
        timeAway : { type: Number, min: 0, max: 3000 },
        lastUpdated : { type: Date, default: Date.now }
    }]
}],

我正在尝试的是通过每列火车的接收数据,以及每个即将到来的火车站,并将估计的到达时间插入火车站列表。重要的是火车1和火车2可能都到达给定的站点,我只想要一个具有多个预测的站点元素。问题是,我不能使用upsert执行findOneAndUpdate,因为该文档尚不存在。

从子文档(here)上的doc,我尝试过push和addToSet,但这些只是为每个预测创建一个子文档。例如,我会得到:

[{
  stopId: 1234,
  incoming : [{
    vehicleId : 11,
    timeAway : 200
  }]
},
  stopId: 1234,
  incoming : [{
    vehicleId : 22,
    timeAway : 400
  }]
}]

我想要的地方:

[{
  stopId: 1234,
  incoming : [{
    vehicleId : 11,
    timeAway : 200
  },{
    vehicleId : 22,
    timeAway : 400
  }]
}]

我觉得我错过了创建此文档的一些基本方面。

1 个答案:

答案 0 :(得分:1)

对于数据架构,

var StationSchema = new mongoose.Schema({
    tableId: String,
    stations: [{
        stopId: String,
        incoming: [{
            vehicleId: String,
            timeAway: {type: Number, min: 0, max: 3000},
            lastUpdated: {type: Date, default:  Date.now}
        }]
    }]
});

通过

保存数据
var s = new Station({
    tableId: '2'
});

s.save(function(err) {

结果

{ "_id" : ObjectId("56e68bcf851a00680832ef13"), "tableId" : "2", "stations" : [ ], "__v" : 0 }

我们知道stations的默认值是空数组,这是mongoose的设计行为。 upsert: true将添加一个不适用于子文档的新文档。

要插入工作站子文档,我们可以先检查stopId是否存在,如果不存在,则插入新工作站子文档。否则,我们可以将新的incoming子文档插入stations。以下是示例代码

Station
    .findOneAndUpdate({tableId: '2', 'stations.stopId': {$exists: false}}, 
                     {$addToSet: {stations: {stopId: '1234', incoming: []}}},
                   function (err, doc){
                        if (err)
                            console.log(err);
                        else{
                            Station
                                .findOneAndUpdate( 
                                  {'stations.stopId': 1234}, 
                                  {$addToSet: {'stations.$.incoming': {vehicleId: 22, timeAway: 400}}}, 
                                  function(err, doc) {
                                    if (err)
                                        console.log(err);
                                    else
                                        console.log(doc);
                                  });

                        }
                   });