Mongodb RxJava:对于异步保存和检索NoSql DB中的数据,建议使用哪种发射器(即反应式方法)

Mongodb RxJava:对于异步保存和检索NoSql DB中的数据,建议使用哪种发射器(即反应式方法),mongodb,rx-java,rx-java2,reactive,reactivex,Mongodb,Rx Java,Rx Java2,Reactive,Reactivex,上下文:这是我第一次使用RxJava 使用RxJava编码时,(1)从NoSql DB中选择文档,(2)插入NoSql(例如MongoDb),考虑到反应堆栈,推荐的emmitter是什么 例如,我通常应该使用Flowable进行阅读,使用Single进行保存吗 这段代码可以很好地将从卡夫卡主题收到的消息保存到MongoDb,但我想知道io.reactivex.Single是否是实现这一点的最佳方法 import com.mongodb.client.result.InsertOneResult

上下文:这是我第一次使用RxJava

使用RxJava编码时,(1)从NoSql DB中选择文档,(2)插入NoSql(例如MongoDb),考虑到反应堆栈,推荐的emmitter是什么

例如,我通常应该使用Flowable进行阅读,使用Single进行保存吗

这段代码可以很好地将从卡夫卡主题收到的消息保存到MongoDb,但我想知道io.reactivex.Single是否是实现这一点的最佳方法

import com.mongodb.client.result.InsertOneResult
import com.mongodb.reactivestreams.client.MongoClient
import com.mongodb.reactivestreams.client.MongoCollection
import io.micronaut.configuration.kafka.annotation.KafkaKey
import io.micronaut.configuration.kafka.annotation.KafkaListener
import io.micronaut.configuration.kafka.annotation.OffsetReset
import io.micronaut.configuration.kafka.annotation.Topic
import io.micronaut.messaging.annotation.Body
import io.reactivex.Observable
import io.reactivex.Single
import javax.inject.Inject
import io.reactivex.functions.Function

@KafkaListener(offsetReset = OffsetReset.EARLIEST)
class DebitConsumer {

    @Inject
    lateinit var mongoClient: MongoClient

    @Topic("debit")
    fun receive(@KafkaKey key: String, name: String) {

        save(key.toInt(), name)

    }

    private fun save( id: Int?,name: String?) {
        val debitMessage =  DebitMessage(id, name)
        Single
                .fromPublisher(getCollection().insertOne(debitMessage))
                .map<DebitMessage>(Function<InsertOneResult, DebitMessage> { debitMessage })
                .subscribe()
    }

    private fun getCollection(): MongoCollection<DebitMessage?> {
        return mongoClient
                .getDatabase("mydb")
                .getCollection("mycollection", DebitMessage::class.java)
    }
}
import com.mongodb.client.result.InsertOneResult
导入com.mongodb.reactivestreams.client.MongoClient
导入com.mongodb.reactivestreams.client.MongoCollection
导入io.micronaut.configuration.kafka.annotation.KafkaKey
导入io.micronaut.configuration.kafka.annotation.KafkaListener
导入io.micronaut.configuration.kafka.annotation.OffsetReset
导入io.micronaut.configuration.kafka.annotation.Topic
导入io.micronaut.messaging.annotation.Body
导入io.reactivex.Observable
导入io.reactivex.Single
导入javax.inject.inject
导入io.reactivex.functions.Function
@KafkaListener(offsetReset=offsetReset.earlime)
类DebitConsumer{
@注入
lateinit var mongoClient:mongoClient
@主题(“借方”)
趣味接收(@KafkaKey:String,name:String){
保存(key.toInt(),名称)
}
私人娱乐存储(id:Int?,名称:String?){
val debitMessage=debitMessage(id,name)
单身
.fromPublisher(getCollection().insertOne(debitMessage))
.map(函数{debitMessage})
.subscribe()
}
private fun getCollection():MongoCollection{
返回mongoClient
.getDatabase(“mydb”)
.getCollection(“mycollection”,DebitMessage::class.java)
}
}

我来自Spring数据,它在反应式世界中有点像积垢,出于这个问题的不相关原因,我将不使用Spring,我正在寻找在反应式/无阻塞/背压世界中写入/读取数据的最佳实践。

您的代码看起来不错。一个
单条
对于保存是有意义的,因为您只能返回一个结果<代码>可流动的对于阅读来说是有意义的,但真正的选择取决于您和您的应用程序。是否要通过侦听数据库更改?然后您必须使用
Flowable
,以便对流中的多个更新做出反应。使用
Flowable
可能是一种很好的做法,即使当前您没有收听多个更新,但您认为将来可能会这样做


如果您确定只想处理一个事件,请使用
Single
。这将为您的应用程序代码处理多个事件的可能性节省一些精力。

我认为,由于您每次调用
save
时都会创建一个新的事件,因此您不会从这里的被动模式中获得任何好处。您的目标是将每个save调用推送到单个流中吗?@CarsonHolzheimer,谢谢。我的主要目标是使用无阻塞方式保存从卡夫卡收到的数据。我所说的“无阻塞”是指避免大量资源,就像线程在完成之前停止一样。如果我做了一些愚蠢的事情,你可以建议如何用RxJava达到这个目的,或者指出原因吗?关于你的问题,不,我的目的不是将每个save调用推送到一个流中。您可以立即订阅。简单地说,在过去,我用Spring数据与mono…subscribe()进行了类似的编码,假设我将其设计为消耗更少的资源(线程)。希望我没有做一些愚蠢的事情,因为代码已经升级了。所以,你看到一些奇怪的期望,善意地建议它,我认为你的代码很好。只是它没有使用任何反应流功能,它只是像一个回调。我看到Mongo已经删除了他们的异步驱动程序,取而代之的是反应式流驱动程序,所以我认为要获得异步行为,您必须像以前一样使用该驱动程序。顺便说一句,我很确定这行
.map…
没有做任何事情。为了澄清,它使用了MongoDBs反应流驱动程序的功能,该驱动程序将写入操作移动到后台线程,因此提供了非阻塞写入。然而,这并不是真正的“反应流”特性,只是在不同的线程上进行异步写入。请参阅此链接了解我困惑的原因: