猫鼬创建一个包含分类子文档的新文档

Mongoose create a new document with catergorized sub documents

本文关键字:文档 新文档 分类 一个 创建 包含      更新时间:2023-09-26

我一直在浏览猫鼬文档,我认为我缺少一些关于它如何工作的基本理解。

我想做什么

我正在进行第三方 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 可能都到达给定的车站,我只想要一个具有多个预测的车站元素。问题是,我无法使用更新器进行查找OneAndUpdate,因为该文档尚不存在。

从关于子文档的文档(这里),我尝试了推送和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
  }]
}]

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

对于数据架构,

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的默认值是空数组,这是猫鼬的设计行为。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);
                                  });
                        }
                   });