복붙노트

[SPRING] 봄철 mongodb에 JSON 스키마 저장하기

SPRING

봄철 mongodb에 JSON 스키마 저장하기

나는 Spring 데이터와 mongodb에 익숙하지 않다. JSON 스키마를 나타내는 JSON 객체가 있고이를 스프링 데이터를 사용하여 mongodb에 저장해야합니다. 하지만 JSON 스키마의 문제는 JSON 스키마의 구조가 동적이라는 것입니다. 예를 들어 완전히 다른 구조를 가진 두 개의 유효한 JSON 스키마가 아래에 나와 있습니다.

{
    "type": "object",
    "properties": {
        "name": {
            "type": "string",
            "minLength": 10
        },
        "age": {
            "type": "integer"
        }
    },
    "required": [
        "name",
        "age"
    ]
}
{
    "type": "array",
    "items": {
        "type": "object",
        "properties": {
            "abc": {
                "type": "boolean"
            },
            "xyz": {
                "$ref": "#/definitions/"
            },
            "asd": {
                "type": "null"
            }
        },
        "required": [
            "abc",
            "xyz"
        ]
    }
}

위의 JSON을 정의 된 클래스와 매핑하여 mongodb에 저장할 수 있도록 JAJO POJO 클래스를 어떻게 정의 할 수 있습니까? 또는 POJO 클래스에 매핑하지 않고 봄에 CURD 연산을 수행 할 수 있습니까?

해결법

  1. ==============================

    1.MongoTemplate을 사용하고 Gson / Jackson을 사용하여 직렬화 및 황폐화하는 것이 좋습니다.

    MongoTemplate을 사용하고 Gson / Jackson을 사용하여 직렬화 및 황폐화하는 것이 좋습니다.

    Mongo Template은 컬렉션 이름과 DBObject 엔티티를 취하는 CRUD 메소드를 가지고 있습니다.이 엔티티는 mongo java 드라이버를 직접 사용하는 경우와 매우 유사합니다.

    그래서 json 페이로드를 가지고 mapper 라이브러리 중 하나를 사용하여지도로 변환 할 것입니다.

    좋아요.

    Deserialise

    ObjectMapper mapper = new ObjectMapper(); 
    TypeReference<HashMap<String,Object>> typeRef 
            = new TypeReference<HashMap<String,Object>>() {};
    HashMap<String,Object> map = mapper.readValue(jsonpayload, typeRef); 
    

    DBObject

    DBObject dbObject = new BasicDBObject(map);
    

    몽고 템플릿

    mongoTemplate.save(dbObject, "collectionname");
    

    다른 모든 CRUD 작업과 유사한 작업을 수행 할 수 있습니다.

  2. ==============================

    2.여기에 필요한 코드를 찾으십시오.

    여기에 필요한 코드를 찾으십시오.

    @lombok.Data
    @JsonInclude(JsonInclude.Include.NON_NULL)
    @JsonIgnoreProperties(ignoreUnknown = true)
    public class Bounty {
    
      String type;
      Map<String, Object> items;
      Map<String, Object> properties;
      List<Object> required;
    }
    

    내 저장소 클래스는 다음과 같습니다.

    public interface BountyRepository extends MongoRepository<Bounty, String> {
    }
    

    그리고 그것을 사용하기 위해 사용할 수있는 컨트롤러 스 니펫이 있습니다.

    @GetMapping("/insert/{number}")
        public void insert(@PathVariable int number){
            bountyRepository.save(getBounty(number));
        }
    
    
        public Bounty getBounty(int number){
            ObjectMapper objectMapper = new ObjectMapper();
            String jsonString1 = "{\n" +
                "    \"type\": \"object\",\n" +
                "    \"properties\": {\n" +
                "        \"name\": {\n" +
                "            \"type\": \"string\",\n" +
                "            \"minLength\": 10\n" +
                "        },\n" +
                "        \"age\": {\n" +
                "            \"type\": \"integer\"\n" +
                "        }\n" +
                "    },\n" +
                "    \"required\": [\n" +
                "        \"name\",\n" +
                "        \"age\"\n" +
                "    ]\n" +
                "}";
    
    
            String jsonString2 = "{\n" +
                "    \"type\": \"array\",\n" +
                "    \"items\": {\n" +
                "        \"type\": \"object\",\n" +
                "        \"properties\": {\n" +
                "            \"abc\": {\n" +
                "                \"type\": \"boolean\"\n" +
                "            },\n" +
                "            \"xyz\": {\n" +
                "                \"$ref\": \"#/definitions/\"\n" +
                "            },\n" +
                "            \"asd\": {\n" +
                "                \"type\": \"null\"\n" +
                "            }\n" +
                "        },\n" +
                "        \"required\": [\n" +
                "            \"abc\",\n" +
                "            \"xyz\"\n" +
                "        ]\n" +
                "    }\n" +
                "}";
    
            try {
                Bounty bounty1 = objectMapper.readValue(jsonString1, Bounty.class);
                Bounty bounty2 = objectMapper.readValue(jsonString2, Bounty.class);
    
    
                if (number == 1) return bounty1;
                if (number == 2) return bounty2;
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }
    

    이것은 구원 후에 몽고에서와 같이 보입니다.

    /* 1 */
    {
        "_id" : ObjectId("58da2390fde4f133178499fa"),
        "_class" : "pani.kiran.sumne.model.Bounty",
        "type" : "object",
        "properties" : {
            "name" : {
                "type" : "string",
                "minLength" : 10
            },
            "age" : {
                "type" : "integer"
            }
        },
        "required" : [ 
            "name", 
            "age"
        ]
    }
    
    /* 2 */
    {
        "_id" : ObjectId("58da23adfde4f133178499fb"),
        "_class" : "pani.kiran.sumne.model.Bounty",
        "type" : "array",
        "items" : {
            "type" : "object",
            "properties" : {
                "abc" : {
                    "type" : "boolean"
                },
                "xyz" : {
                    "$ref" : "#/definitions/"
                },
                "asd" : {
                    "type" : "null"
                }
            },
            "required" : [ 
                "abc", 
                "xyz"
            ]
        }
    }
    
  3. ==============================

    3.내 프로젝트에서는 필자의 모델이 매우 동적 인 구조를 가졌고 java.util.Map 객체를 사용하여 매핑했습니다.

    내 프로젝트에서는 필자의 모델이 매우 동적 인 구조를 가졌고 java.util.Map 객체를 사용하여 매핑했습니다.

    이것이 내 mondo 문서 모델이 구현 된 방법입니다.

    @Document(collection = "e_form_data")
    public class FormDataModel extends AbstractModel
    {
        private static final long serialVersionUID = -1733975205300782871L;
        @Field
        @Indexed(name = "e_form_id_idx")
        private String eFormId;
        @Field
        private Map<String, Object> eFormData;
    
        public FormDataModel()
        {
            super();
        }
    
        public FormDataModel(String id, String creatoDa, String modificatoDa, Date dataCreazione, Date dataModifica, String eFormId, Map<String, Object> eFormData)
        {
            super(id, creatoDa, modificatoDa, dataCreazione, dataModifica);
            this.eFormData = eFormData;
            this.eFormId = eFormId;
        }
    
        public FormDataModel(Map<String, Object> eFormData)
        {
            super();
            this.eFormData = eFormData;
        }
    
        public Map<String, Object> geteFormData()
        {
            return eFormData;
        }
    
        public void seteFormData(Map<String, Object> eFormData)
        {
            this.eFormData = eFormData;
        }
    
        public String geteFormId()
        {
            return eFormId;
        }
    
        public void seteFormId(String eFormId)
        {
            this.eFormId = eFormId;
        }
    
        public String getDataInserimento()
        {
            return Utils.formatDateTime(new DateTime(this.dataCreazione.getTime()), "dd/MM/yyyy");
        }
    
        @Override
        public String toString()
        {
            return "FormDataModel [eFormId=" + eFormId + ", eFormData=" + eFormData + "]";
        }
    
    }
    

    이 모든 것을 사용하면 꽤 잘됩니다.

  4. ==============================

    4.@DBref를 사용하여 포함 된 문서를 매핑 할 수 있습니다.

    @DBref를 사용하여 포함 된 문서를 매핑 할 수 있습니다.

    @Document(collection = "first")
    public class First {
    
        @Id
        private String id;
    
        @DBRef
        private Properties properties;
    
        @Field
        private List<String> required;
    
        // constructor
        // getters and setter    
    }
    
    public class Properties {
    
        @Id
        private String id;
    
        @DBRef
        private Name name;
    
        @DBRef
        private Age age;
    
        // constructor
        // getters and setter   
    }
    
    public class Name { ... }
    public class Age { ... }
    

    http://www.baeldung.com/cascading-with-dbref-and-lifecycle-events-in-spring-data-mongodb

    http://docs.spring.io/spring-data/data-mongo/docs/1.4.2.RELEASE/reference/html/mapping-chapter.html#mapping-usage-references

    또는 Angelo Immediata가 제안했듯이

    @Document(collection = "first")
    public class First {
    
        @Id
        private String id;
    
        @Field
        private Map<String, Object> properties;
    
        @Field
        private List<String> required;
    
        // constructor
        // getters and setter    
    }
    

    그리고 사용자 정의 읽기 및 쓰기 변환기가 필요합니다.

    http://docs.spring.io/spring-data/data-mongo/docs/1.4.2.RELEASE/reference/html/mapping-chapter.html#mapping-explicit-converters

  5. ==============================

    5.FWIW, MongoDB 3.6에서는 데이터베이스 수준에서 JSON Schema Validation 지원을 도입했습니다. MongoDB의 블로그에서 더 많은 것을 읽을 수 있습니다. 그게 조금 도움이 되었길 바래요!

    FWIW, MongoDB 3.6에서는 데이터베이스 수준에서 JSON Schema Validation 지원을 도입했습니다. MongoDB의 블로그에서 더 많은 것을 읽을 수 있습니다. 그게 조금 도움이 되었길 바래요!

  6. from https://stackoverflow.com/questions/42973756/storing-a-json-schema-in-mongodb-with-spring by cc-by-sa and MIT license