Mongodb
ファイルからJson
にデータをインポートするのに苦労しています。
コマンドラインでもmongoimport command
を使用して同じことができます。
たくさん調べて試しましたが、Javaを使用してJsonファイルからインポートできませんでした。
sample.json
{ "test_id" : 1245362, "name" : "ganesh", "age" : "28", "Job" :
{"company name" : "company1", "designation" : "SSE" }
}
{ "test_id" : 254152, "name" : "Alex", "age" : "26", "Job" :
{"company name" : "company2", "designation" : "ML" }
}
お時間をいただきありがとうございます。 〜ガネーシャ〜
JSON文字列をそれぞれ読み取ることができるとします。たとえば、最初のJSONテキストを読みます
{ "test_id" : 1245362, "name" : "ganesh", "age" : "28", "Job" :
{"company name" : "company1", "designation" : "SSE" }
}
それを変数(String json1)に割り当てます。次のステップは、それを解析することです。
DBObject dbo = (DBObject) com.mongodb.util.JSON.parse(json1);
すべてdboをリストに入れ、
List<DBObject> list = new ArrayList<>();
list.add(dbo);
次に、それらをデータベースに保存します。
new MongoClient().getDB("test").getCollection("collection").insert(list);
編集:
最新のMongoDBバージョンでは、DBObjectの代わりにDocumentsを使用する必要があり、オブジェクトを追加する方法が異なって見えるようになりました。更新された例を次に示します。
インポートは次のとおりです。
import com.mongodb.MongoClient;
import com.mongodb.client.MongoDatabase;
import org.bson.Document;
コードはこれを望みます(編集の上のテキストを参照):
Document doc = Document.parse(json1);
new MongoClient().getDataBase("db").getCollection("collection").insertOne(doc);
リストを使ってそれを行うこともできます。しかし、あなたは必要です
new MongoClient().getDataBase("db").getCollection("collection").insertMany(list);
しかし、私はこの解決策に問題があると思います。入力するとき:
db.collection.find()
コレクション内のすべてのオブジェクトを取得するためのmongoシェルでは、結果は次のようになります。
{ "_id" : ObjectId("56a0d2ddbc7c512984be5d97"),
"test_id" : 1245362, "name" : "ganesh", "age" : "28", "Job" :
{ "company name" : "company1", "designation" : "SSE"
}
}
これは以前とまったく同じではありません。
ランタイムr = Runtime.getRuntime();
プロセスp = null;
--dirは、mongoimportがある場所へのパスです。
File dir = new File( "C:\ Program Files\MongoDB\Server\3.2\bin");
-この行は、dirを指定してシェルを開きます。インポートのコマンドは、コマンドプロモートでmongoimportを使用するのとまったく同じです。
p = r.exec( "c:\ windows\system32\cmd.exe/c mongoimport --db mydb --collection student --type csv --file student.csv --headerline"、null、dir );
私自身も同様の「問題」を抱えていて、 Jackson と POJO databinding 、およびMorphiaを使用することになりました。
これはスレッジハンマーでナットを割るような音ですが、実際には非常に使いやすく、堅牢で非常にパフォーマンスが高く、コードを賢く維持するのも簡単です。
小さな注意点:再利用する場合は、test_id
フィールドをMongoDBの_id
にマップする必要があります。
JSONファイルからPOJOにデータをマップする方法をJacksonにヒントする必要があります。読みやすくするために、クラスを少し短くしました。
@JsonRootName(value="person")
@Entity
public class Person {
@JsonProperty(value="test_id")
@Id
Integer id;
String name;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
埋め込みドキュメントJob
については、リンクされているPOJOデータバインディングの例をご覧ください。
アプリケーションの初期化中のどこかで、注釈付きのPOJOをマップする必要があります。すでにMongoClientを持っているはずなので、それを再利用します;)
Morphia morphia = new Morphia();
morphia.map(Person.class);
/* You can reuse this datastore */
Datastore datastore = morphia.createDatastore(mongoClient, "myDatabase");
/*
* Jackson's ObjectMapper, which is reusable, too,
* does all the magic.
*/
ObjectMapper mapper = new ObjectMapper();
これで、特定のJSONファイルのインポートが同じくらい簡単になります
public Boolean importJson(Datastore ds, ObjectMapper mapper, String filename) {
try {
JsonParser parser = new JsonFactory().createParser(new FileReader(filename));
Iterator<Person> it = mapper.readValues(parser, Person.class);
while(it.hasNext()) {
ds.save(it.next());
}
return Boolean.TRUE;
} catch (JsonParseException e) {
/* Json was invalid, deal with it here */
} catch (JsonMappingException e) {
/* Jackson was not able to map
* the JSON values to the bean properties,
* possibly because of
* insufficient mapping information.
*/
} catch (IOException e) {
/* Most likely, the file was not readable
* Should be rather thrown, but was
* cought for the sake of showing what can happen
*/
}
return Boolean.FALSE;
}
少し再ファットコアを作成することで、これをJacksonアノテーション付きBeanの汎用インポーターに変換できます。明らかに、私はいくつかの特別なケースを省略しましたが、これはこの回答の範囲外になります。
List<Document> jsonList = new ArrayList<Document>();
net.sf.json.JSONArray array = net.sf.json.JSONArray.fromObject(json);
for (Object object : array) {
net.sf.json.JSONObject jsonStr = (net.sf.json.JSONObject)JSONSerializer.toJSON(object);
Document jsnObject = Document.parse(jsonStr.toString());
jsonList.add(jsnObject);
}
collection.insertMany(jsonList);
3.2ドライバーでは、mongoコレクションとjsonドキュメントのコレクションがある場合(例:
MongoCollection<Document> collection = ...
List<String> jsons = ...
個別に挿入できます。
jsons.stream().map(Document::parse).forEach(collection::insertOne);
またはバルク:
collection.insertMany(
jsons.stream().map(Document::parse).collect(Collectors.toList())
);
私は今日この問題に直面し、別の方法で解決しましたが、ここでは誰も私を満足させませんでしたので、私の余分な貢献を楽しんでください。パフォーマンスは、30kのドキュメントをエクスポートし、統合テストケース用にSpringbootアプリにインポートするのに十分です(数秒かかります)。
まず、最初にデータをエクスポートする方法が重要です。 Javaアプリで解析できる1つのドキュメントが各行に含まれているファイルが必要でした。
mongo db --eval 'db.data.find({}).limit(30000).forEach(function(f){print(tojson(f, "", true))})' --quiet > dataset.json
次に、resourcesフォルダーからファイルを取得して解析し、行を抽出して、mongoTemplateで処理します。バッファを使用できます。
@Autowired
private MongoTemplate mongoTemplate;
public void createDataSet(){
mongoTemplate.dropCollection("data");
try {
InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(DATASET_JSON);
List<Document> documents = new ArrayList<>();
String line;
InputStreamReader isr = new InputStreamReader(inputStream, Charset.forName("UTF-8"));
BufferedReader br = new BufferedReader(isr);
while ((line = br.readLine()) != null) {
documents.add(Document.parse(line));
}
mongoTemplate.insert(documents,"data");
} catch (Exception e) {
throw new RuntimeException(e);
}
}