elasticsearch,worker,changestream,Node.js,Mongodb,elasticsearch,Worker,Changestream" /> elasticsearch,worker,changestream,Node.js,Mongodb,elasticsearch,Worker,Changestream" />

Node.js 如何实现将数据从mongo流到elasticsearch的nodeJS worker?

Node.js 如何实现将数据从mongo流到elasticsearch的nodeJS worker?,node.js,mongodb,elasticsearch,worker,changestream,Node.js,Mongodb,elasticsearch,Worker,Changestream,我正在构建一个基于的应用程序,该应用程序用于近实时地侦听elasticsearch中的更改事件和索引更改 到目前为止,我已经实现了一个worker,它调用一个函数来捕获事件、转换事件并在elasticsearch中为它们编制索引,在实现1 mongo集合流时没有任何问题: function syncChangeEvents() { const stream = ModelA.watch() while (!stream.isClosed()) { if (await stream

我正在构建一个基于的应用程序,该应用程序用于近实时地侦听elasticsearch中的更改事件和索引更改

到目前为止,我已经实现了一个worker,它调用一个函数来捕获事件、转换事件并在elasticsearch中为它们编制索引,在实现1 mongo集合流时没有任何问题:

function syncChangeEvents() {
  const stream = ModelA.watch()
  while (!stream.isClosed()) {
    if (await stream.hasNext()) {
      const event = stream.next()
      // transform event
      // index to elasticsearch
    }
  }
}
我已经使用无限循环(可能是一种糟糕的方法)实现了它,但我不确定当我必须让变更流永远保持活力时,还有什么替代方案

当我必须为另一个模型实现变更流时,问题就出现了。因为第一个函数有一个阻塞的while循环,所以工人不能调用第二个函数来启动第二个变更流


我想知道,最好的办法是让一个工人能够触发x个变更流,而不会影响每个变更流的性能。工作线程是正确的方法吗?

在Node.js中,有三种主要的方法来处理更改流

  • 您可以使用EventEmitter的函数监视更改流

     // See https://mongodb.github.io/node-mongodb-native/3.3/api/Collection.html#watch for the watch() docs
     const changeStream = collection.watch(pipeline);
    
     // ChangeStream inherits from the Node Built-in Class EventEmitter (https://nodejs.org/dist/latest-v12.x/docs/api/events.html#events_class_eventemitter).
     // We can use EventEmitter's on() to add a listener function that will be called whenever a change occurs in the change stream.
     // See https://nodejs.org/dist/latest-v12.x/docs/api/events.html#events_emitter_on_eventname_listener for the on() docs.
     changeStream.on('change', (next) => {
         console.log(next);
     });
    
     // Wait the given amount of time and then close the change stream
     await closeChangeStream(timeInMs, changeStream);
    
  • 您可以使用监视更改流

  • 您可以使用流API监控变更流

     // See https://mongodb.github.io/node-mongodb-native/3.3/api/Collection.html#watch for the watch() docs
     const changeStream = collection.watch(pipeline);
    
     // See https://mongodb.github.io/node-mongodb-native/3.3/api/ChangeStream.html#pipe for the pipe() docs
     changeStream.pipe(
         new stream.Writable({
             objectMode: true,
             write: function (doc, _, cb) {
                 console.log(doc);
                 cb();
             }
         })
     );
    
     // Wait the given amount of time and then close the change stream
     await closeChangeStream(timeInMs, changeStream);
    
  • 如果MongoDB数据库托管在Atlas()上,最简单的方法就是创建一个数据库。Atlas为您处理更改流代码的编程,因此您只需编写代码来转换事件并在Elasticsearch中对其进行索引


    有关使用更改流和触发器的更多信息,请参见。上面所有代码片段的完整代码示例都可以在上找到。

    在Node.js中使用更改流有三种主要方法

  • 您可以使用EventEmitter的函数监视更改流

     // See https://mongodb.github.io/node-mongodb-native/3.3/api/Collection.html#watch for the watch() docs
     const changeStream = collection.watch(pipeline);
    
     // ChangeStream inherits from the Node Built-in Class EventEmitter (https://nodejs.org/dist/latest-v12.x/docs/api/events.html#events_class_eventemitter).
     // We can use EventEmitter's on() to add a listener function that will be called whenever a change occurs in the change stream.
     // See https://nodejs.org/dist/latest-v12.x/docs/api/events.html#events_emitter_on_eventname_listener for the on() docs.
     changeStream.on('change', (next) => {
         console.log(next);
     });
    
     // Wait the given amount of time and then close the change stream
     await closeChangeStream(timeInMs, changeStream);
    
  • 您可以使用监视更改流

  • 您可以使用流API监控变更流

     // See https://mongodb.github.io/node-mongodb-native/3.3/api/Collection.html#watch for the watch() docs
     const changeStream = collection.watch(pipeline);
    
     // See https://mongodb.github.io/node-mongodb-native/3.3/api/ChangeStream.html#pipe for the pipe() docs
     changeStream.pipe(
         new stream.Writable({
             objectMode: true,
             write: function (doc, _, cb) {
                 console.log(doc);
                 cb();
             }
         })
     );
    
     // Wait the given amount of time and then close the change stream
     await closeChangeStream(timeInMs, changeStream);
    
  • 如果MongoDB数据库托管在Atlas()上,最简单的方法就是创建一个数据库。Atlas为您处理更改流代码的编程,因此您只需编写代码来转换事件并在Elasticsearch中对其进行索引


    有关使用更改流和触发器的更多信息,请参见。上面所有代码片段的完整代码示例都可以在上找到。

    为什么不订阅<代码>stream.on('change',next=>{//处理下一个文档})谢谢@GwenM,这个方法也很有效。您建议如何让工作进程保持活动状态,以便我可以创建多个监听不同集合的流?为什么不订阅呢<代码>stream.on('change',next=>{//处理下一个文档})谢谢@GwenM,这个方法也很有效。您建议如何让工作人员保持活动状态,以便我可以创建多个监听不同集合的流?谢谢@Lauren。为了了解如何实现变更流,我已经多次参考了您的博客文章。对于非触发解决方案,您建议如何保持Node.js进程无限期运行,以便它能够捕获流发出的所有事件?以上三种解决方案都会在一定时间后显式关闭更改流。您可以省略这些调用以保持更改流处于打开状态。在某个时刻,您的应用程序可能会失去与变更流的连接。请确保存储恢复令牌,以便您可以在上次中断的位置重新打开更改流。有关更多详细信息,请参阅博客文章的这一部分:谢谢。我已经使用
    startAfter
    选项实现了恢复变更流的逻辑。在这方面,当
    startAfter
    似乎是一个更好的选项时,mongodb有什么理由继续支持
    resumeAfter
    选项吗?
    startAfter
    是在mongodb 4.2中添加的,该版本于2019年8月正式发布
    resumeAfter
    可能仍然支持从以前的版本升级。对,明白了。谢谢你,劳伦!谢谢你,劳伦。为了了解如何实现变更流,我已经多次参考了您的博客文章。对于非触发解决方案,您建议如何保持Node.js进程无限期运行,以便它能够捕获流发出的所有事件?以上三种解决方案都会在一定时间后显式关闭更改流。您可以省略这些调用以保持更改流处于打开状态。在某个时刻,您的应用程序可能会失去与变更流的连接。请确保存储恢复令牌,以便您可以在上次中断的位置重新打开更改流。有关更多详细信息,请参阅博客文章的这一部分:谢谢。我已经使用
    startAfter
    选项实现了恢复变更流的逻辑。在这方面,当
    startAfter
    似乎是一个更好的选项时,mongodb有什么理由继续支持
    resumeAfter
    选项吗?
    startAfter
    是在mongodb 4.2中添加的,该版本于2019年8月正式发布
    resumeAfter
    可能仍然支持从以前的版本升级。对,明白了。谢谢你,劳伦!