简体   繁体   English

如何使用 MongoDB Scala 驱动程序将聚合结果累积到集合中

[英]How to accumulate aggregation results into a collection using MongoDB Scala Driver

I am migrating a code that I myself made in Java to Scala which does an aggregation in MongoDB.我正在将自己在 Java 中编写的代码迁移到 Scala,该代码在 MongoDB 中进行聚合。 But I was stuck on how to accumulate the results of aggregation inside a collection using MongoDB Scala Driver.但是我被困在如何使用 MongoDB Scala 驱动程序在集合中累积聚合结果。

Java code:爪哇代码:

mongoCollection.aggregate(aggregatePipeline)
    .map(document -> {
      Document group = document.get("_id", Document.class);
      return new Document("chat", group).append("count", document.get("count"));
    })
    .into(new ArrayList<>(), (results, e) -> {
      Document document = new Document("chats", results);
      System.out.println(document.toJson());
    });

Scala code:斯卡拉代码:

mongoCollection.aggregate(aggregatePipeline)
    .map[Document](doc => Document("chat" -> doc.get("_id"), "count" -> doc.get("count")))
    .subscribe((doc: Document) => println(doc.toJson))

As can be seen in the code in Scala, I'm not accumulating the aggregation results, because I do not know how to get the same behavior from the .into() method present in the Java code, using the MongoDB Scala Driver.从 Scala 的代码中可以看出,我没有累积聚合结果,因为我不知道如何使用 MongoDB Scala 驱动程序从 Java 代码中的 .into() 方法中获得相同的行为。 I've done a lot of research on the internet, but without success.我在互联网上做了很多研究,但没有成功。 If anyone can help me, I appreciate it.如果有人可以帮助我,我将不胜感激。

You should use the implicit Observable helpers specifically collect() .您应该专门使用隐式Observable 助手collect() There is also a toFuture() method that effectively runs collect and returns the result as a Future .还有一个toFuture()方法可以有效地运行 collect 并将结果作为Future返回。

mongoCollection.aggregate(aggregatePipeline)
    .map[Document](doc => Document("chat" -> doc.get("_id"), "count" -> doc.get("count")))
    .collect()
    .subscribe((docs: Seq[Document]) => println(docs))

You can setup a variable of Seq[Document] type and then append the resulting document sequence to the variable once the subscription event fires.您可以设置 Seq[Document] 类型的变量,然后在订阅事件触发后将生成的文档序列附加到变量中。 Use Promise/Future to wait for the result.使用 Promise/Future 等待结果。 For example:例如:

def find_all (collection_name: String): Seq[Document] = {

    /* The application will need to wait for the find operation thread to complete in order to process the returned value. */

    log.debug(s"Starting database find_all operation thread")

    /* Set up new client connection, database, and collection */
    val _client: MongoClient = MongoClient(config_client)
    val _database: MongoDatabase = _client.getDatabase(config_database)
    val collection: MongoCollection[Document] = _database.getCollection(collection_name)

    /* Set up result sequence */
    var result_seq : Seq[Document] = Seq.empty

    /* Set up Promise container to wait for the database operation to complete */
    val promise = Promise[Boolean]

    /* Start insert operation thread; once the thread has finished, read resulting documents. */
    collection.find().collect().subscribe((results: Seq[Document]) => {
      log.trace(s"Found operation thread completed")
      /* Append found documents to the results */
      result_seq = result_seq ++ results
      log.trace(s" Result sequence: $result_seq")

     /* set Promise container */      
     promise.success(true)

     /* close client connection to avoid memory leaks */
      _client.close
     })

    /* Promise completion result */
    val future = promise.future

    /* wait for the promise completion result */
    Await.result(future, Duration.Inf)
    /* Return document sequence */
    result_seq

  }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM