node js中的异步编程通过mongoose模型传递常量/预定义的强制值

Posted

技术标签:

【中文标题】node js中的异步编程通过mongoose模型传递常量/预定义的强制值【英文标题】:Asynchronous Programming in node js to pass constants/predefined mandatory values through mongoose model 【发布时间】:2019-01-21 00:25:59 【问题描述】:

我有多个问题,请查看我的代码。

1) 如何通过模型传递常量/预定义的强制值?

例如。我有一些字段,用户必须在 kafkaSchema.config[] 和 livySchema.args[] 中传递值和一些常量。我想通过的代码在同一个问题线程的第二个问题中。

 const mongoose = require('mongoose');


const livy_schema = mongoose.Schema(
    file:  type: String, required: true ,
    name:  type: String, required: true ,
    className:  type: String, required: true ,
    args: [ type: mongoose.Schema.Types.Mixed, required: true ] //here i have constants to pass on to 
);

const kafka_schema = mongoose.Schema(
    _id: mongoose.Schema.Types.ObjectId,
    name:  type: String, required: true, unique: false ,
    config:  type: mongoose.Schema.Types.Mixed, required: true  //here i have constants to pass on to 
);


const enrichedEventSchema = mongoose.Schema(
    _id: mongoose.Schema.Types.ObjectId,
    projectId:  type: mongoose.Schema.Types.ObjectId, ref: 'Project', required: true ,
    name:  type: String, required: true, unique: true ,
    description:  type: String, required: false ,
    type:  type: String, enum: ["Enriched"], required: true ,
    format:  type: String, enum: ["JSON", "DELIMITED", "FixedWidth", "LOG"], required: true ,
    kafka: [kafka_schema],
    livy: [livy_schema]  // how to make this schema required:true?
);

module.exports = mongoose.model('EnrichedEvent', enrichedEventSchema);

2) 如何让这段代码异步运行,现在它同步运行。例如,它能够将事件数据保存在数据库中的事件集合中,然后更新项目集合,然后调用 axios.post 方法依次调用我的 livy 服务器和 kafka 服务器。我想要做的是将事件数据保存在数据库的事件集合中,然后更新项目集合(同步),同时我想同时(异步)调用我的 livy 和 kafka 服务器。

router.post("/:projectId/events/enriched", (req, res, next) => 
    const enrichedEvent = new EnrichedEvent(
        _id: mongoose.Types.ObjectId(),
        name: req.body.name,
        projectId: req.params.projectId, //taking from url
        description: req.body.description,
        type: req.body.type,
        format: req.body.format,
        kafka: req.body.kafka,
        livy: req.body.livy
    );
    enrichedEvent.save()
        .then(result => 
            console.log(result);
            res.status(201).json(
                message: "Event stored",
                createdEvent: 
                    _id: result._id,
                    projectId: result.projectId,
                    name: result.name,
                    description: result.description,
                    type: result.type,
                    kafka: result.kafka,
                    livy: result.livy
                
            );

            Project.findOneAndUpdate( _id: result.projectId ,
                 $push:  enrichedEvents: result._id  )
            axios.post("http://52.xxx.xxx.199:8998/batches", result.livy)
                .then(function (response) 
                    console.log(response);
                )
                .then(axios.get("http://52.xxx.xxx.199:8998/batches/"), function (res) 
                    console.log(res);
                )
            axios.post("http://52.xxx.xxx.199:8083/connectors", result.kafka)
                .then(function (response) 
                    console.log(response);
                )
                .catch(err => 
                    console.log(err);
                    res.status(500).json(
                        error: err
                    );
                );
        );
);

问题可能看起来有点冗长,但在 SO 上提出的问题是有效的。请指引我正确的方向。

【问题讨论】:

请将其分成 2 个单独的问题,范围更有限。你的问题是too broad,就像现在写的那样。 @zero298 ***.com/questions/51871045/… 哥们,你去吧...并且还支持这个问题,因为...我正处于被 SO 禁止的边缘 【参考方案1】:

1)

const enrichedEventSchema = mongoose.Schema(
    // ...
    livy:  type: [livy_schema], required: true 
);

2)

return enrichedEvent.save().
  then(result => 
    // ...
    return Project.findOneAndUpdate(/*...*/);
  ).
  then(() => 
    // ...
    return Promise.all([axios.post(/*...*/), axios.post(/*...*/]);
  );

【讨论】:

我没想到@vkarpov15 会回答我的问题...实际上第一个问题是关于我每次发布数据时是否可以传递一些硬编码值。我猜你已经在代码中看到了我的评论并回答了它,这对我来说也是必需的。无论如何我会编辑问题。 本帖第一个问题已转发***.com/questions/51871045/… 第一个答案不起作用,livy: type: [livy_schema], required: true 。请提供替代解决方案。【参考方案2】:

嘿,试试以下:

1) 用于保存用户输入的配置并具有默认常量。你可以使用猫鼬pre save钩子。

https://mongoosejs.com/docs/middleware.html#pre

livy_schema.pre('save', function(next) 
  this.args =  ...this.args, ...CONSTANTS ; //I'm use es6's spread operator
  next();
);

kafka_schema.pre('save', function(next) 
  this.config =  ...this.config, ...CONSTANTS ; //I'm use es6's spread operator
  next();
);

2)第二个问题:尝试以下:

axios.all([
  axios.post("http://52.221.178.199:8998/batches", result.livy),
  axios.post("http://52.221.178.199:8083/connectors", result.kafka)
]);

【讨论】:

这是第二个问题。它的工作,你能回答问题1吗? @darshanan 我已经更新了我的答案,请看看这是否能解决您的问题。

以上是关于node js中的异步编程通过mongoose模型传递常量/预定义的强制值的主要内容,如果未能解决你的问题,请参考以下文章

Node.js/Mongoose 等待异步 For 循环

node.js 中间件 mongoose

创建 Schema Mongoose (Node.js) 模型以简化代码

Mongoose使用小结

白洁血战Node.js并发编程 002 异步

在 Node.js 的异步函数中填充数组