有 Java 编程相关的问题?

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

mongodb Java Spring Boot无法从值为hashmap的键读取结果

我有一个简单的服务器从mongodb读取所有日志,但是数据库中的一些数据的result属性的格式不同

其结果属性的值类似于hashmap:

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

 "transaction_id":"c2c986a96a0cfa7fc96619733449fd88c9d685bf704a50d07baef74f6
}

然后对于result属性,它会为我返回一个空结果, 但是如果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;
  }
}

共 (1) 个答案

  1. # 1 楼答案

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

    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