4 Java注解:一個真實的Elasticsearch案例

昨天把拼了一半的注解+Elasticsearch積木放下了,因為東西太多了拼不好,還容易亂 。休息了一晚上接著來 。
接著昨天,創建elasticsearch文檔注解(相當于數據表的注解):
/** * elastic文檔注解 , 定義每個elasticsearch文檔上的屬性 * * @author xiangwang */@Inherited@Retention(RetentionPolicy.RUNTIME)@Target({ ElementType.TYPE })public @interface Document {String index();String type() default "_doc";boolean useServerConfiguration() default false;short shards() default 1;short replicas() default 0;String refreshInterval() default "1s";String indexStoreType() default "fs";}然后再創建elasticsearch文檔(相當于數據表):
/** * elastic文檔對象 * * @author xiangwang */@Document(index = "document", type = "_doc", shards = 1, replicas = 0)public class ElasticDocument {private static final long serialVersionUID = 2879048112350101009L;// 文檔編碼@DocField(name = "guid", type = FieldType.Keyword)protected String guid = "";// 標題@DocField(name = "title", type = FieldType.Text, analyzer = "ik_max_word", searchAnalyzer = "ik_max_word")protected String title = "";// 文檔創建時間(資源實際創建時間)@DocField(name = "createtime", type = FieldType.Long)protected long createtime;// 文檔更新時間(資源實際更新時間)@DocField(name = "updatetime", type = FieldType.Long)protected long updatetime;public ElasticDocument() {}public String getGuid() {return guid;}public void setGuid(String guid) {this.guid = guid;}public String getTitle() {return title;}public void setTitle(String title) {this.title = title;}public long getCreatetime() {return createtime;}public void setCreatetime(long createtime) {this.createtime = createtime;}public long getUpdatetime() {return updatetime;}public void setUpdatetime(long updatetime) {this.updatetime = updatetime;}@Overridepublic String toString() {return String.format("{\"guid\":\"%s\", \"title\":\"%s\", \"createtime\":%d, " +"\"updatetime\":%d}", guid, title, createtime, updatetime);}}這里面的@Document就是剛才創建的文檔注解 。
最后 , 創建一個真正的執行者 , 就由它來完成所有材料的拼裝:
/** * ElasticDao * * @author xiangwang */@Componentpublic class ElasticDao {// ElasticConfiguration中定義的Bean對象@Autowiredprivate RestHighLevelClient client;/*** 索引是否存在**/public boolean indexExist(final String index) {try {return client.indices().exists(new GetIndexRequest(index), RequestOptions.DEFAULT);} catch (IOException e) {System.out.println("index exist exception");}return false;}/*** 解析類注解,獲取包括父類字段在內的所有字段* 因為解析的時候,會把父類及自身的一些額外字段給解析進去* 如logger、serialVersionUID等* 所以需要把這些無用的字段排除掉* 這里不存在繼承,所以直接調用clazz.getDeclaredFields()* 另外,如果存在繼承關系,該怎么處理呢?(可以思考一下)**/public static List<Field> getAllDeclaredFields(Class<?> clazz) {return new ArrayList<>(Arrays.asList(clazz.getDeclaredFields()));}/*** 創建索引,前面都是為了實現它作準備* 這里會通過注解 , 一路解析文檔的字段,拼接成可執行的腳本交給elasticsearch的api去執行**/public boolean createIndex(final String index, final Class<?> clazz) {try {Document document = (Document) clazz.getAnnotation(Document.class);int shards = document.shards();int replicas = document.replicas();if (indexExist(index)) {return false;}CreateIndexRequest request = new CreateIndexRequest(index);request.settings(Settings.builder().put("index.number_of_shards", shards).put("index.number_of_replicas", replicas));StringBuilder builder = new StringBuilder();builder.append("{\n");builder.append("\"properties\": {\n");List<Field> list = getAllDeclaredFields(clazz);int length = list.size();for (int i = 0; i < length; i++) {DocField docField = list.get(i).getAnnotation(DocField.class);if (null == docField) {continue;}builder.append("\"").append(docField.name()).append("\" : {\n");builder.append("\"type\" : \"").append(docField.type().value).append("\"");if (docField.index()) {builder.append(", \n");builder.append("\"index\" : ").append(docField.index());}if (docField.fielddata()) {builder.append(", \n");builder.append("\"fielddata\" : ").append(docField.fielddata());}if (docField.store()) {builder.append(", \n");builder.append("\"store\" : ").append(docField.store());}if (StringUtils.isNotBlank(docField.analyzer())) {builder.append(", \n");builder.append("\"analyzer\" : \"").append(docField.analyzer()).append("\"");}if (StringUtils.isNotBlank(docField.format())) {builder.append(", \n");builder.append("\"format\" : \"").append(docField.format()).append("\"");}if (StringUtils.isNotBlank(docField.searchAnalyzer())) {builder.append(", \n");builder.append("\"search_analyzer\" : \"").append(docField.searchAnalyzer()).append("\"");}if (StringUtils.isNotBlank(docField.pattern())) {builder.append(", \n");builder.append("\"pattern\" : \"").append(docField.pattern()).append("\"");}if (StringUtils.isNotBlank(docField.normalizer())) {builder.append(", \n");builder.append("\"normalizer\" : \"").append(docField.normalizer()).append("\"");}if (i == length -1) {builder.append("\n}\n");} else {builder.append("\n}, \n");}}builder.append("}\n");builder.append("}\n");request.mapping(JSON.parseObject(builder.toString()).toJSONString(), XContentType.JSON);CreateIndexResponse response = client.indices().create(request, RequestOptions.DEFAULT);boolean acknowledged = response.isAcknowledged();return acknowledged;} catch (IOException e) {System.out.println("create index exception");}return false;}}

推薦閱讀