有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java Scala块映射

我在一个项目中使用Scala,我有以下情况:

我正在读一个csv文件,我的结构如下:

mail,file,action
ex1@...,file1,insert
ex2@...,file2,update

我的mongodb中有三个集合:用户、文件、操作和;操作引用文件和用户ID

模式应该是这样的:

Action {
 actionName: String,
 userId: ObjectId, 
 fileId: ObjectId 
}

问题是我在读取csv时没有这些ID。它们是在阅读过程中产生的。所以我的主要问题是:当用户和文件在您试图使用它们时被插入时,如何引用它们

我最初的解决方案是创建3个踏板来保存代码的每一部分,并使用两个映射:Map1[userMail,Ids]和Map2[fileName,Ids]。在数据库中插入一个用户或文件后,代码将获取他们各自的ID并放入地图中

同时,我有一个线程来保存操作。当这个线程同时拥有两个ID时,它会将这些映射集中起来。无论何时,它都会保存操作(我们称之为“操作线程”)。比如:

while(filesMap.get(action.fileId) == None) {
  Thread.sleep(1000)
}
while(usersMap.get(action.userId) == None) {
  Thread.sleep(1000)
} ... //save code omitted for clarity

这段代码可以工作,但问题是它太慢了。我相信“action thread”一直在用它的池锁定map,从而阻止了实际上正在将数据保存到db的线程的一些写操作

所以,我的问题是:有没有更智能的方法来通知“操作线程”ID存在并删除池代码,或者,有没有更好的方法在scala中开箱即用

我使用promises和resolve在Javascript中做了类似的事情,但由于我在Scala工作不到一个月,我不知道如何移植代码

谢谢


共 (2) 个答案

  1. # 2 楼答案

    How to reference users and files when they're inserted at the moment you're trying to use them

    你需要加入

    mongodb

    流式处理真实数据库中的所有内容,并在那里进行连接。在Scala中实现基本上是手工重新实现半个数据库

    如果内存无限,可以在Scala不可变集合中加载所有内容:

    val filesMap: Map[Int, File] = ...
    val userMap: Map[Int, User] = ...
    
    val actions: Stream[Action] =
      csv.lines.map(csvParser).flatMap { case (actionName, userId, fileId) =>
        for {
          file <- filesMap.get(fileId)
          user <- userMap.get(userId)
        } yield
          Action(actionName, user, file)
      }