SolrJ で JSON をインポートする


#課題

SolrJ ではドキュメントをインポートするのに「SolrInputDocument」クラスを使うことになっていますが、JSONからSolrInputDocumentに変換する機能は提供されていないようなので作りました。
フィールドのタイプをプロパティで指定できるようにしてあります。

#Code

```java
import java.io.IOException;
import java.util.Properties;

import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.impl.HttpSolrClient;
import org.apache.solr.client.solrj.response.UpdateResponse;
import org.apache.solr.common.SolrInputDocument;

import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;

public class SolrJsonImporter {

	SolrClient client;
	Properties props;

	public SolrJsonImporter(String endPoint) {
		client = new HttpSolrClient.Builder(endPoint).build();
	}

	public UpdateResponse add(String json) throws SolrServerException, IOException {

		SolrInputDocument document = new SolrInputDocument();
		JsonObject jsonObj = (JsonObject) new Gson().fromJson(json, JsonObject.class);
		if (this.props == null) {
			for (String key : jsonObj.keySet()) {
				String value = jsonObj.get(key).getAsString();
				document.addField(key, value);
			}

		} else {
			processFields(jsonObj, document, this.props);

		}

		UpdateResponse response = client.add(document); // throws SolrServerException,IOException
		return response;

	}

	private void processFields(JsonObject jsonObj, SolrInputDocument document, Properties props) {
		for (int n = 0; true; n++) {
			String propKey = String.format("field[%d]", n);
			String fieldName = props.getProperty(propKey + ".name");
			if (fieldName == null) {
				break;
			}

			String fieldType = props.getProperty(propKey + ".type");

			System.err.println(fieldName + "," + fieldType);

			String fieldTarget = props.getProperty(propKey + ".target", fieldName);

			Object oValue = null;

			if (fieldType.equals("String")) {
				oValue = jsonObj.get(fieldName).getAsString();
			} //
			else if (fieldType.equals("String[]")) {
				JsonArray arr = jsonObj.get(fieldName).getAsJsonArray();
				Object[] oo = new Object[arr.size()];
				for (int x = 0; x < arr.size(); x++) {
					oo[x] = arr.get(x).getAsString();
				}
				oValue = oo;
			} //
			else if (fieldType.equals("Long")) {
				oValue = jsonObj.get(fieldName).getAsLong();
			} //
			else if (fieldType.equals("Long[]")) {
				JsonArray arr = jsonObj.get(fieldName).getAsJsonArray();
				Object[] oo = new Object[arr.size()];
				for (int x = 0; x < arr.size(); x++) {
					oo[x] = arr.get(x).getAsLong();
				}
				oValue = oo;
			} //
			else if (fieldType.equals("Double")) {
				oValue = jsonObj.get(fieldName).getAsDouble();
			} //
			else if (fieldType.equals("Double[]")) {
				JsonArray arr = jsonObj.get(fieldName).getAsJsonArray();
				Object[] oo = new Object[arr.size()];
				for (int x = 0; x < arr.size(); x++) {
					oo[x] = arr.get(x).getAsDouble();
				}
				oValue = oo;
			} //
			document.addField(fieldTarget, oValue);
		}

	}

	public UpdateResponse commit() throws IOException, SolrServerException {
		return client.commit();
	}

	private void setProperties(Properties props) {
		this.props = props;

	}

}

```

#使い方

```java
String urlString = "http://localhost:8983/solr/sandbox";
Properties props = new Properties();
props.setProperty("debug", "false");
props.setProperty("field[0].name", "id");
props.setProperty("field[0].type", "String");
props.setProperty("field[1].name", "text");
props.setProperty("field[1].type", "String");
props.setProperty("field[2].name", "field1");
props.setProperty("field[2].type", "String");
props.setProperty("field[3].name", "field2");
props.setProperty("field[3].type", "String[]");
props.setProperty("field[4].name", "field3");
props.setProperty("field[4].type", "Long[]");
props.setProperty("field[5].name", "field4");
props.setProperty("field[5].type", "Double[]");
props.setProperty("field[6].name", "field5");
props.setProperty("field[6].type", "Long");
props.setProperty("field[7].name", "field6");
props.setProperty("field[7].type", "Double");

String json = "{" //
		+ "'id':'001'" //
		+ ",'text':'This is test.'" //
		+ ",'field1':'fieldvalue001'" //
		+ ",'field2':['fieldvalue001']" //
		+ ",'field3':[1,2,3]" //
		+ ",'field4':[0.1,0.2,0.3]" //
		+ ",'field5':123" //
		+ ",'field6':0.123" //
		+ "}";

SolrJsonImporter util = new SolrJsonImporter(urlString);
util.setProperties(props);

System.err.println(util.add(json));

util.commit();

```

#まとめ

このクラスを使うと簡単にJSONをSolrJ経由でインポートすることができます。
既存のJSONがあり、適当に変換してインポートしたい場合に便利なのではないかと思います。