【问题标题】:Mongoose create a new document with catergorized sub documentsMongoose 创建一个包含分类子文档的新文档
【发布时间】:2016-06-28 04:46:17
【问题描述】:

我一直在浏览 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) 中,我尝试了 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
  }]
}]

我觉得我缺少创建此文档的一些基本方面。

【问题讨论】:

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


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

    【讨论】:

    • 问题是,stopId 为 1234 的给定站可能还不存在。要使用 findOneAndUpdate,我必须创建一个新文档,但我需要使用 upsert,文档指出您不能将其与 $ 运算符一起使用。 docs.mongodb.org/manual/reference/operator/update/positional/…。为了解决这个问题,我正在尝试使用“var newDoc = new Schema({ tableId : '1' } );”,但我找不到一种方法来让相同的 findOneAndUpdate 发生 upsert 行为。
    猜你喜欢
    • 2019-10-05
    • 2018-09-03
    • 2022-01-17
    • 2016-04-30
    • 2015-10-31
    • 2013-03-02
    • 2020-01-16
    • 2015-10-13
    • 2020-04-20
    相关资源
    最近更新 更多