问题
JSON.parse()
from mongo (Java driver) returns either a BasicDBList or a BasicDBObject.
However, when migrating to mongo driver 3.x, what's the new parse method that returns either Document
or List<Document>
?
In the new driver, Document.parse()
only parses an object, not an array (throws an exception when given an array).
What is the equivalent of JSON.parse() for Arrays with 3.x Java drivers ?
回答1:
A simple trick to parse any JSON and to get either Document
or List<Document>
:
Document.parse("{\"json\":" + json + "}").get("json")
回答2:
To parse JSON string data using the mongodb java driver 3.x:
Parse JSON document:
Use the Document.parse()
static method to parse a single JSON document.
Document doc = Document.parse("{\"objA\":{\"foo\":1}}");
Parse JSON array:
Use an instance of BsonArrayCodec
to decode a JsonReader
.
For example:
final String JSON_DATA
= "[{\"objA\":{\"foo\":1}},"
+ "{\"objB\":{\"bar\":2}}]";
final CodecRegistry codecRegistry = CodecRegistries.fromProviders(asList(new ValueCodecProvider(),
new BsonValueCodecProvider(),
new DocumentCodecProvider()));
JsonReader reader = new JsonReader(JSON_DATA);
BsonArrayCodec arrayReader = new BsonArrayCodec(codecRegistry);
BsonArray docArray = arrayReader.decode(reader, DecoderContext.builder().build());
for (BsonValue doc : docArray.getValues()) {
System.out.println(doc);
}
ref: http://api.mongodb.org/java/3.2/org/bson/json/JsonReader.html, http://api.mongodb.org/java/3.2/org/bson/codecs/BsonArrayCodec.html
回答3:
How about this:
Document doc = new Document("array", JSON.parse("[ 100, 500, 300, 200, 400 ]", new JSONCallback()));
System.out.println(doc.toJson()); //prints { "array" : [100, 500, 300, 200, 400] }
回答4:
You're right that there's no easy equivalent.
If you use line-delimited JSON documents instead of a JSON array, it becomes fairly straightforward:
List<Document> getDocumentsFromLineDelimitedJson(final String lineDelimitedJson) {
BufferedReader stringReader = new BufferedReader(
new StringReader(lineDelimitedJson));
List<Document> documents = new ArrayList<>();
String json;
try {
while ((json = stringReader.readLine()) != null) {
documents.add(Document.parse(json));
}
} catch (IOException e) {
// ignore, can't happen with a StringReader
}
return documents;
}
For example, this call
System.out.println(getDocumentsFromLineDelimitedJson("{a : 1}\n{a : 2}\n{a : 3}"));
will print:
[Document{{a=1}}, Document{{a=2}}, Document{{a=3}}]
回答5:
The easiest equivalent for me is to use any json library to convert the json to POJO. Below is an example using jackson:
String input = "[{\"objA\":{\"foo\":1}},{\"objB\":{\"bar\":2}}]";
ObjectMapper mapper = new ObjectMapper();
List<Document> output = (List<Document>) mapper.readValue(input, List.class)
.stream().map(listItem -> new Document((LinkedHashMap)listItem))
.collect(Collectors.toList());
回答6:
Added cast to @Oleg Nitz answer, for completeness.
Object object = Document.parse("{\"json\":" + jsonData.getJson() + "}").get("json");
if (object instanceof ArrayList) {
documents = (ArrayList<Document>) object;
} else (object instanceof Document) {
document = (Document) object;
}
来源:https://stackoverflow.com/questions/34436952/json-parse-equivalent-in-mongo-driver-3-x-for-java