【问题标题】:Java Spring Boot can't read result from keys whose value is a hashmapJava Spring Boot 无法从值为 hashmap 的键中读取结果
【发布时间】:2018-09-26 18:32:34
【问题描述】:

我有一个简单的服务器从 mongodb 读取所有日志,但是 db 中的某些数据的结果属性具有不同的格式。

其中一个结果属性的值类似于哈希图:

{
    "event_name" : "Transfer", 
    "result" : { "_from" : "0x928c9af0651632157ef27a2cf17ca72c575a4d21", 
                   "_value" : "1111", 
                 "_to"  :"0x143449e55cdd2a5bae081f041650ba9089812a95" },  

 "transaction_id":"c2c986a96a0cfa7fc96619733449fd88c9d685bf704a50d07baef74f6
}

那么对于 result 属性,它会为我返回一个空结果, 但是如果结果属性是这样的,就像一个数组:

"result" : ["0x928c9af0651632157ef27a2cf17ca72c575a4d21",  "1111", "0x143449e55cdd2a5bae081f041650ba9089812a95"],

然后它会输出结果值。 问题是它在 mongodb 中同时具有两种格式,有什么方法可以同时处理这两种不同格式的结果属性?

import com.alibaba.fastjson.JSONArray;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.io.Serializable;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.Field;

@Document(collection = "eventLog")
public class EventLogEntity implements Serializable {

  private static final long serialVersionUID = -70777625567836430L;

  @Id
  private String id;

  @Field(value = "block_number")
  @JsonProperty(value = "block_number")
  private long blockNumber;

  @Field(value = "block_timestamp")
  @JsonProperty(value = "block_timestamp")
  private long blockTimestamp;

  @Field(value = "contract_address")
  @JsonProperty(value = "contract_address")
  private String contractAddress;

  @Field(value = "event_name")
  @JsonProperty(value = "event_name")
  private String entryName;

  @Field(value = "result")
  @JsonProperty(value = "result")
  private JSONArray resultJsonArray;

  @Field(value = "transaction_id")
  @JsonProperty(value = "transaction_id")
  private String transactionId;

  public EventLogEntity(long blockNumber, long blockTimestamp, String contractAddress,
      String entryName, JSONArray resultJsonArray, String transactionId) {
    this.blockNumber = blockNumber;
    this.blockTimestamp = blockTimestamp;
    this.contractAddress = contractAddress;
    this.entryName = entryName;
    this.resultJsonArray = resultJsonArray;
    this.transactionId = transactionId;
  }

  public static long getSerialVersionUID() {
    return serialVersionUID;
  }

  public long getBlockNumber() {
    return blockNumber;
  }

  public void setBlockNumber(long blockNumber) {
    this.blockNumber = blockNumber;
  }

  public long getBlockTimestamp() {
    return blockTimestamp;
  }

  public void setBlockTimestamp(long blockTimestamp) {
    this.blockTimestamp = blockTimestamp;
  }

  public String getContractAddress() {
    return contractAddress;
  }

  public void setContractAddress(String contractAddress) {
    this.contractAddress = contractAddress;
  }

  public String getEntryName() {
    return entryName;
  }

  public void setEntryName(String entryName) {
    this.entryName = entryName;
  }

  public JSONArray getResultJsonArray() {
    System.out.println(resultJsonArray.toString());
    return resultJsonArray;
  }

  public void setResultJsonArray(JSONArray resultJsonArray) {
    this.resultJsonArray = resultJsonArray;
  }

  public String getTransactionId() {
    return transactionId;
  }

  public void setTransactionId(String transactionId) {
    this.transactionId = transactionId;
  }
}

【问题讨论】:

    标签: java mongodb spring-boot


    【解决方案1】:

    首先,您有 2 个不同的文档实体,如果您确实需要保留两种格式并阅读其中一种,则每个结构都应该有一个实体。 一个实体将如您所描述的那样,另一个将具有如下结果属性:

    public class ResultObject{
       private String _from;
       private String _value;
       private String _to;
    
       //getters, setters & constructor
    }
    

    并且您将此 ResultObject 引用为其他实体的属性:

    public class EventLogEntityWithResultObject implements Serializable{
    ...
    private ResultObject result;
    ...
    }
    

    如果您不需要保留这两种结构,您可以使用 MongoDB 命令将所有文档从一种结构类型迁移到另一种结构类型,例如:Change document structure in mongodb with the mongo shell

    【讨论】:

    • 好吧,我把 JSONArray 类型改成 Object,它可以工作,但只是不确定这是否是个好主意
    • 看你的需要,如果你需要同时支持这两种类型的实体,把它们分成两个类也不错。这是因为它们具有不同的结构,您应该单独编写代码以正确解析它。我强烈认为尝试将两种结构都放在一个实体中是个坏主意。当您的模型(即实体)发生接口更改时,通常会将 mongo 的所有当前数据迁移到新的模型结构中,这就是为什么我问您是否真的需要保留这两种类型的结构
    • 结构不同。其他一些实体可能有不同的键值对,例如,其他一些数据可能有结果:{ _num: 6, result: 36, id: 334}。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-02-11
    • 2018-01-07
    • 2018-09-15
    • 1970-01-01
    • 2021-03-05
    • 2019-04-06
    • 2018-06-24
    相关资源
    最近更新 更多