MongoDb:findAndModify从表中删除类型信息

时间:2017-10-10 20:32:37

标签: mongodb spring-data-mongodb

我需要从springboot应用程序中使用mongoDb findAndModify。但是,在更新时,将删除表中的_class列。如果没有此列,springboot将无法对数据进行编组。

在客户端我使用带有org.springframework.data:spring-data-mongodb:1.10.6.RELEASE

的java

我的mongoDb服务器版本= 3.4.7

这是以前的行:

> coll.find( {"_id":"job-20"} )
{ "_id" : "job-20", 
  "_class" :  "org.alleninstitute.aics.statustracker.JobStatus", 
  "steps" : [{ 
    "step" : "busted", 
    "stepStatus" : { 
      "_class" :  "org.alleninstitute.aics.statustracker.states.Blocked", 
      "by" : [ "jag", "zig" ] 
    } 
  }, 
  { "step" : "zig", 
    "stepStatus" : { 
      "_class" : "org.alleninstitute.aics.statustracker.states.Working", 
      "host" : "GPU-X001", 
      "message" : "the landing is secured" 
    } 
  }, 
  { "step" : "jag", 
    "stepStatus" : {
      "_class" : "org.alleninstitute.aics.statustracker.states.Succeeded", 
      "host" : "GEO-01" 
    } 
  } ], 
  "version" : 2 }
  

这是以后的行:

{
"_id": "job-20",
"_class": "org.alleninstitute.aics.statustracker.JobStatus",
"steps": [{
    "step": "busted",
    "stepStatus": {
        "host": "galangal",
        "message": "used in thai food"
    }
}, {
    "step": "zig",
    "stepStatus": {
        "host": "GPU-X001",
        "message": "the landing is secured"
    }
}, {
    "step": "jag",
    "stepStatus": {
        "host": "GEO-01"
    }
}],
"version": 3

}

使用MongoOperations.save保留_class。但我需要使用MongoOperations.findAndModify来实现其并发更新功能。

我想知道是否会有一个简单的解决方法。

这是用于原子更新的代码:

private JobStatus updateStep(JobStatus jobStatus, String step, StepStatus stepStatus) {//updates the passed jobStatus and returns the updated object}

@PostMapping("/status/update")
public JobStatus update(@RequestBody StepAndStepStatus stepAndStepStatus)      {

    String jobId = "job-20";
    String step = stepAndStepStatus.step;
    StepStatus stepStatus = stepAndStepStatus.stepStatus;

    while (true) {
        JobStatus oldJobStatus = repo.findByJobId(jobId);
        if (oldJobStatus == null)
          throw new IllegalArgumentException(String.format("no job with jobId: %s", jobId));

        JobStatus updatedJobStatus = updateStep(oldJobStatus, step, stepStatus);
        Query query = new Query();
        query.addCriteria(Criteria.where("version").is(oldJobStatus.version));
        query.addCriteria(Criteria.where("_id").is(jobId));

        Update update = new Update();
        update.set("steps", updatedJobStatus.steps);
        update.set("version", oldJobStatus.version + 1);

        JobStatus os = mongoOperation.findAndModify(query, update, JobStatus.class);
        if (os != null)
            return updatedJobStatus;
    }

}

POJO:

public class JobStatus {
  @Id
  public String jobId;
  @JsonSubTypes.Type(value = LinkedList.class)
  public List<StepAndStepStatus> steps;

  public int version;

  public JobStatus() {}


  public JobStatus(String jobId, List<StepAndStepStatus> steps, int version) {
    this.jobId = jobId;
    this.steps = steps;
    this.version = version;
  }

  @Override
  public String toString() {
    return String.format("Job[id=%s, steps=%s, version=%d]", jobId, steps.toString(), version);
  }

}

public class StepAndStepStatus {
  public String step;
  public StepStatus stepStatus;
  public StepAndStepStatus(String step, StepStatus stepStatus) {
    this.step = step;
    this.stepStatus = stepStatus;
  }
  public StepAndStepStatus() {}
  public String toString() {
    return String.format("step: %s stepStatus: %s", step, stepStatus);
  }
}

public class Blocked extends StepStatus {
  // The set of steps that block this step
  public Set<String> by;
  public Blocked() {this(Collections.<String>emptySet());}
  public Blocked(Set<String> by) {
    super();
    this.by = by;
  }
  public boolean active() {return true;}
  public boolean failed() {return false;}
  public String toString() {
    return String.format("by: %s ", by);
  }
}

public class Working extends StepStatus {
  public String host;
  public String message;
  public Working(String host, String message) {
    super();
    this.host = host;
    this.message = message;
  }
  public Working() {this("", "");}
  public String toString() {
    return String.format("host: %s message: %s", host, message);
  }
  public boolean active() {return true;}
  public boolean failed() {return false;}

}

public class Succeeded extends StepStatus {
  public String host;
  public Succeeded(String host) {
    super();
    this.host = host;
  }
  public boolean active() {return false;}
  public boolean failed() {return false;}
  public Succeeded() {this("");}
  public String toString() {
    return String.format("host: %s", host);
  }

}

@JsonTypeInfo(
  use = JsonTypeInfo.Id.NAME,
  include = JsonTypeInfo.As.PROPERTY,
  property = "type")
@JsonSubTypes({
  @Type(value = Waiting.class, name = "waiting"),
  @Type(value = Working.class, name = "working"),
  @Type(value = Retrying.class, name = "retrying"),
  @Type(value = Blocked.class, name = "blocked"),
  @Type(value = Succeeded.class, name = "succeeded"),
  @Type(value = Failed.class, name = "failed")
})
public abstract class StepStatus {
  public abstract boolean active();
  public abstract boolean failed();
}

0 个答案:

没有答案
相关问题