I have to come up with a design, basically a configuration that I can pass to a Mongo Reader job, to convert the read document(json) to a flat json structure. for eg(excuse the made up eg). Idea is that the json can be of any structure, but i should be able to control the output of the reader based on my mapping that i provide to this job.
animal: { dog: { name: pluto, age: 4 }, cat: { name: mini, age: 1 }, hamster: { name: jack age: 0.3 } }
TO
animals: [{ type: dog, name: pluto, age: 4 }, { type: cat, name: mini, age: 1 }, { type: hamster, name: jack, age: 1 } ]
Prepare utilities
Converters.java
import org.bson.Document;
import org.bson.json.Converter;
import org.bson.json.JsonMode;
import org.bson.json.JsonWriterSettings;
import org.bson.json.StrictJsonWriter;
import org.bson.types.ObjectId;
import java.util.List;
import java.util.stream.Collectors;
public class Converters {
private Converters () {
}
private static class ObjectIdConverter implements Converter<ObjectId> {
public static final Converters.ObjectIdConverter INSTANCE = new Converters.ObjectIdConverter();
@Override
public void convert(ObjectId value, StrictJsonWriter writer) {
writer.writeString(value.toHexString());
}
}
private static final JsonWriterSettings JSON_WRITER_SETTINGS = JsonWriterSettings
.builder()
.outputMode(JsonMode.RELAXED)
.objectIdConverter(Converters.ObjectIdConverter.INSTANCE)
.build();
public static String bsonToJson(Document bson) {
return bson == null ? null : bson.toJson(JSON_WRITER_SETTINGS);
}
public static String bsonListToJson(List<Document> bsonList) {
return bsonList == null || bsonList.isEmpty() ? null :
"[" + bsonList.stream()
.map(Converters::bsonToJson)
.collect(Collectors.joining(",")) +
"]";
}
}
JsonDao.java
import org.bson.BsonDocument;
import org.bson.BsonValue;
import org.bson.Document;
import org.bson.codecs.BsonArrayCodec;
import org.bson.codecs.DecoderContext;
import org.bson.json.JsonReader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.BasicQuery;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
@Component
public class JsonDao {
@Autowired
private MongoTemplate mongoTemplate;
public List<Document> findDocuments(String collectionName, String query, String projection) {
return mongoTemplate.find(
new BasicQuery(query, projection),
Document.class,
collectionName
);
}
public List<Document> aggregateDocuments(String collectionName, String operations) {
List<BsonDocument> pipeline = new BsonArrayCodec()
.decode(new JsonReader(operations), DecoderContext.builder().build())
.stream()
.map(BsonValue::asDocument)
.collect(Collectors.toList());
return mongoTemplate.getDb().getCollection(collectionName).aggregate(pipeline).into(new ArrayList<>());
}
public String findJsonString(String collectionName, String query, String projection) {
return bsonToJson(mongoTemplate.findOne(
new BasicQuery(query, projection),
Document.class,
collectionName
));
}
public String findJsonArrayString(String collectionName, String query, String projection) {
return bsonListToJson(findDocuments(collectionName, query, projection));
}
public String aggregateJsonString(String collectionName, String operations) {
List<Document> documents = aggregateDocuments(collectionName, operations);
return documents.isEmpty() ? null : bsonToJson(documents.get(0));
}
public String aggregateJsonArrayString(String collectionName, String operations) {
return bsonListToJson(aggregateDocuments(collectionName, operations));
}
}
Usage
implementation 'com.octomix.josson:josson:1.3.21'
-------------------------------------------------
String json = jsonDao.findJsonString(<collectionName>, <findOneQuery>, <projection>);
Josson josson = Josson.fromJsonString(json);
JsonNode node = josson.getNode(<transformationQuery>);
// Then use Jackson ObjectMapper to convert JsonNode to POJO
Test transformation
Josson josson = Josson.fromJsonString(
"{\n" +
" \"animal\": {\n" +
" \"dog\": {\n" +
" \"name\": \"pluto\",\n" +
" \"age\": 4\n" +
" },\n" +
" \"cat\": {\n" +
" \"name\": \"mini\",\n" +
" \"age\": 1\n" +
" },\n" +
" \"hamster\": {\n" +
" \"name\": \"jack\",\n" +
" \"age\": 0.3\n" +
" }\n" +
" }\n" +
"}");
JsonNode node = josson.getNode(
"animal.map(animals: entries().map(type:key, name:value.name, age:value.age))");
System.out.println(node == null ? null : node.toPrettyString());
Output
{
"animals" : [ {
"type" : "dog",
"name" : "pluto",
"age" : 4
}, {
"type" : "cat",
"name" : "mini",
"age" : 1
}, {
"type" : "hamster",
"name" : "jack",
"age" : 0.3
} ]
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.