Explorar o código

add: 添加搜索相关依赖

许家凯 %!s(int64=4) %!d(string=hai) anos
pai
achega
bb827b058b

+ 34 - 0
pom.xml

@@ -24,6 +24,39 @@
     </properties>
 
     <dependencies>
+
+        <dependency>
+            <groupId>org.elasticsearch</groupId>
+            <artifactId>elasticsearch</artifactId>
+            <version>5.6.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.elasticsearch.client</groupId>
+            <artifactId>elasticsearch-rest-client</artifactId>
+            <version>5.6.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.elasticsearch.client</groupId>
+            <artifactId>elasticsearch-rest-high-level-client</artifactId>
+            <version>5.6.0</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.elasticsearch.client</groupId>
+                    <artifactId>elasticsearch-rest-client</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-aop</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.aliyun.openservices</groupId>
+            <artifactId>ons-client</artifactId>
+            <version>1.8.4.Final</version>
+        </dependency>
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-data-mongodb</artifactId>
@@ -153,6 +186,7 @@
             <version>2.7</version>
         </dependency>
 
+
     </dependencies>
 
     <build>

+ 10 - 0
src/main/java/com/winhc/phoenix/example/PhoenixExampleApplication.java

@@ -1,11 +1,16 @@
 package com.winhc.phoenix.example;
 
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.Bean;
+import org.springframework.scheduling.annotation.EnableScheduling;
 import org.springframework.stereotype.Controller;
 import org.springframework.web.bind.annotation.GetMapping;
 
 @SpringBootApplication
+@EnableScheduling
 @Controller
 public class PhoenixExampleApplication {
 
@@ -17,4 +22,9 @@ public class PhoenixExampleApplication {
     public String te() {
         return "redirect:/swagger-ui.html";
     }
+
+    @Bean
+    public ObjectMapper objectMapper() {
+        return new ObjectMapper().disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
+    }
 }

+ 42 - 0
src/main/java/com/winhc/phoenix/example/aspect/TimeAspect.java

@@ -0,0 +1,42 @@
+package com.winhc.phoenix.example.aspect;
+
+import lombok.extern.slf4j.Slf4j;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Pointcut;
+import org.springframework.stereotype.Component;
+
+/**
+ * @author: XuJiakai
+ * 2020/11/24 17:34
+ */
+@Slf4j
+@Aspect
+@Component
+public class TimeAspect {
+
+    @Pointcut("@annotation(com.winhc.phoenix.example.aspect.Timer)")
+    private void pointcut() {
+    }
+
+    @Around("pointcut()")
+    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
+
+        // 获取目标类名称
+        String clazzName = joinPoint.getTarget().getClass().getName();
+
+        // 获取目标类方法名称
+        String methodName = joinPoint.getSignature().getName();
+
+        long start = System.currentTimeMillis();
+//        log.info("{}.{}(): start...", clazzName, methodName);
+
+        // 调用目标方法
+        Object result = joinPoint.proceed();
+
+        long time = System.currentTimeMillis() - start;
+        log.info("{}.{}(): {} ms", clazzName, methodName, time);
+        return result;
+    }
+}

+ 14 - 0
src/main/java/com/winhc/phoenix/example/aspect/Timer.java

@@ -0,0 +1,14 @@
+package com.winhc.phoenix.example.aspect;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * @author x
+ */
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Timer {
+}

+ 54 - 4
src/main/java/com/winhc/phoenix/example/configuration/ElasticSearchConfiguration.java

@@ -8,9 +8,13 @@ import org.apache.http.impl.client.BasicCredentialsProvider;
 import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
 import org.elasticsearch.client.RestClient;
 import org.elasticsearch.client.RestClientBuilder;
+import org.elasticsearch.client.RestHighLevelClient;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 
+import java.util.stream.Stream;
+
 /**
  * @Author: XuJiakai
  * @Date: 2020/9/15 20:01
@@ -18,14 +22,33 @@ import org.springframework.context.annotation.Configuration;
  */
 @Configuration
 public class ElasticSearchConfiguration {
+    @Value("${es.username}")
+    private String username;
+    @Value("${es.password}")
+    private String password;
+    @Value("${es.host}")
+    private String host;
+
+    @Value("${es.schema:http}")
+    String schema;
+    @Value(value = "${es.connect-timeout:1000}")
+    String connectTimeout;
+    @Value(value = "${es.socket-timeout:600000}")
+    String socketTimeout;
+    @Value(value = "${es.connection-request-timeout:500}")
+    String connectionRequestTimeout;
+    @Value(value = "${es.max-conn-total:100}")
+    String maxConnTotal;
+    @Value(value = "${es.max-conn-per-route:100}")
+    String maxConnPerRoute;
 
     @Bean
     public RestClient bean() {
         final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
         credentialsProvider.setCredentials(AuthScope.ANY,
-                new UsernamePasswordCredentials("USER NAME", "PASSWORD"));
+                new UsernamePasswordCredentials(username, password));
         // 单击所创建的Elasticsearch实例ID,在基本信息页面获取公网地址,即为HOST。
-        return RestClient.builder(new HttpHost("HOST", 9200))
+        return RestClient.builder(new HttpHost(host, 9200))
                 .setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
                     @Override
                     public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {
@@ -35,7 +58,34 @@ public class ElasticSearchConfiguration {
     }
 
 
-    public void b(){
-        RestClient bean = bean();
+    @Bean
+    public RestHighLevelClient getClient() {
+        HttpHost[] httpHosts = Stream.of(host.split(",")).map(host -> {
+            String[] split = host.split(":");
+            return new HttpHost(split[0], 9200, schema);
+        }).toArray(HttpHost[]::new);
+
+        // 阿里云Elasticsearch集群需要basic auth验证。
+        final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
+        //访问用户名和密码为您创建阿里云Elasticsearch实例时设置的用户名和密码,也是Kibana控制台的登录用户名和密码。
+        credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(username, password));
+
+
+        return new RestHighLevelClient(RestClient
+                .builder(httpHosts)
+                .setMaxRetryTimeoutMillis(60000 * 3)
+                .setRequestConfigCallback(builder -> {
+                    builder.setConnectTimeout(!connectTimeout.isEmpty() ? Integer.valueOf(connectTimeout) : 1000);
+                    builder.setSocketTimeout(!socketTimeout.isEmpty() ? Integer.valueOf(socketTimeout) : 60000);
+                    builder.setConnectionRequestTimeout(!connectionRequestTimeout.isEmpty() ? Integer.valueOf(connectionRequestTimeout) : 500);
+                    return builder;
+                })
+                .setHttpClientConfigCallback(httpAsyncClientBuilder -> {
+                    httpAsyncClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
+                    httpAsyncClientBuilder.setMaxConnTotal(!maxConnTotal.isEmpty() ? Integer.valueOf(maxConnTotal) : 100);
+                    httpAsyncClientBuilder.setMaxConnPerRoute(!maxConnPerRoute.isEmpty() ? Integer.valueOf(maxConnPerRoute) : 100);
+                    return httpAsyncClientBuilder;
+                }).build()
+        );
     }
 }

+ 31 - 0
src/main/java/com/winhc/phoenix/example/configuration/RocketMqConfiguration.java

@@ -0,0 +1,31 @@
+package com.winhc.phoenix.example.configuration;
+
+import com.aliyun.openservices.ons.api.ONSFactory;
+import com.aliyun.openservices.ons.api.Producer;
+import com.aliyun.openservices.ons.api.PropertyKeyConst;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import java.util.Properties;
+
+/**
+ * @author: XuJiakai
+ * 2020/10/30 17:13
+ */
+@Configuration
+public class RocketMqConfiguration {
+    public static final String ACCESS_KEY = "LTAIHAdBYQjCFHki";
+    public static final String SECRET_KEY = "sVj8EYkyKRYqdwAF0oY5GzCcTt9h3G";
+    public static final String NAMESRV_ADDR = "http://onsaddr-internet.aliyun.com/rocketmq/nsaddr4client-internet";
+
+    @Bean
+    public Producer rocketmq() {
+        Properties producerProperties = new Properties();
+        producerProperties.setProperty(PropertyKeyConst.AccessKey, ACCESS_KEY);
+        producerProperties.setProperty(PropertyKeyConst.SecretKey, SECRET_KEY);
+        producerProperties.put(PropertyKeyConst.ONSAddr, NAMESRV_ADDR);
+        Producer producer = ONSFactory.createProducer(producerProperties);
+        producer.start();
+        return producer;
+    }
+}

+ 97 - 0
src/main/java/com/winhc/phoenix/example/util/HighlightUtils.java

@@ -0,0 +1,97 @@
+package com.winhc.phoenix.example.util;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * @author: XuJiakai
+ * 2020/12/7 13:57
+ */
+public class HighlightUtils {
+    public static String append(String source, String highlight) {
+        String replace = highlight.replace("<font color='red'>", "\001").replace("</font>", "\002").replace("\002\001", "");
+        int sourceIndex = 0;
+        char[] ghc = replace.toCharArray();
+        int highIndex = 0;
+        char[] chars = source.toCharArray();
+        List<Character> res = new ArrayList<>();
+        for (char c : ghc) {
+            res.add(c);
+        }
+        int delta = 0;
+        int pretotal = -1;
+        int total = 0;
+        while (sourceIndex < chars.length && highIndex < ghc.length) {
+            pretotal = total;
+            total = sourceIndex + highIndex;
+            if (pretotal != 0 && pretotal == total) {
+                ++sourceIndex;
+                ++highIndex;
+                continue;
+            }
+
+            if (ghc[highIndex] == chars[sourceIndex] || (ghc[highIndex] + "").equals(chars[sourceIndex] + "")) {
+                sourceIndex++;
+                highIndex++;
+                continue;
+            }
+            if (chars[sourceIndex] == '(' || chars[sourceIndex] == ')') {
+                if (ghc[highIndex] == '\001') {
+                    if (findLeft(ghc, highIndex)) {
+                        res.add(highIndex + delta, chars[sourceIndex]);
+
+                    } else {
+                        res.add(highIndex + delta + 1, chars[sourceIndex]);
+
+                    }
+                } else {
+                    res.add(highIndex + delta, chars[sourceIndex]);
+                }
+                delta++;
+                sourceIndex++;
+            }
+            if (ghc[highIndex] == '\001' || ghc[highIndex] == '\002') {
+                highIndex++;
+            }
+        }
+        String replace1 = res.stream().map(String::valueOf).collect(Collectors.joining())
+                .replace("(\001", "\001(")
+                .replace("\002)", ")\002")
+                .replace("\002\001", "")
+                .replace("\001", "<font color=\"red\">")
+                .replace("\002", "</font>");
+
+        Map<String, String> collect = source.chars().mapToObj(s -> String.valueOf((char) s)).distinct().collect(Collectors.toMap(s -> s, s -> s, (o, n) -> n));
+
+        if (collect.isEmpty()) {
+            return replace1;
+        }
+        for (Map.Entry<String, String> stringStringEntry : collect.entrySet()) {
+            if (stringStringEntry.getValue().equals(stringStringEntry.getKey())) {
+                continue;
+            }
+            replace1 = replace1.replace(stringStringEntry.getValue(), stringStringEntry.getKey());
+        }
+        return replace1;
+    }
+
+    private static boolean findLeft(char[] chars, int index) {
+        while (index >= 0) {
+            if (chars[index] == '\001') {
+                return true;
+            }
+            if (chars[index] == '\002') {
+                return false;
+            }
+            --index;
+        }
+        return false;
+    }
+
+
+    public static void main(String[] args) {
+        System.out.println(append("百度云智(北京)科技有限公司", "<font color='red'>百度云智</font>北京科技有限公司"));
+    }
+}

+ 19 - 0
src/main/java/com/winhc/phoenix/example/util/JsonUtils.java

@@ -0,0 +1,19 @@
+package com.winhc.phoenix.example.util;
+
+import com.alibaba.fastjson.JSONObject;
+import com.alibaba.fastjson.serializer.SerializerFeature;
+
+/**
+ * @Author: XuJiakai
+ * @Date: 2020/6/22 14:18
+ * @Description:
+ */
+public class JsonUtils {
+    public static String jsonObjToString(Object jsonObject) {
+        return JSONObject.toJSONString(jsonObject, SerializerFeature.WriteMapNullValue);
+    }
+
+    public static String jsonObjToStringNotWriteMapNull(Object jsonObject) {
+        return JSONObject.toJSONString(jsonObject, SerializerFeature.IgnoreNonFieldGetter);
+    }
+}

+ 84 - 0
src/main/java/com/winhc/phoenix/example/util/SortUtil.java

@@ -0,0 +1,84 @@
+package com.winhc.phoenix.example.util;
+
+import org.elasticsearch.script.Script;
+import org.elasticsearch.script.ScriptType;
+import org.elasticsearch.search.sort.ScriptSortBuilder;
+import org.elasticsearch.search.sort.SortOrder;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author: XuJiakai
+ * 2020/11/20 15:33
+ */
+public class SortUtil {
+    public static class SingletonHolder {
+        static SortUtil instance = new SortUtil();
+    }
+
+    public static SortUtil getInstance() {
+        return SortUtil.SingletonHolder.instance;
+    }
+
+
+    public ScriptSortBuilder fastSort = new ScriptSortBuilder(new Script(ScriptType.INLINE, "painless", "return doc['company_score_weight'].value;", new HashMap<>()), ScriptSortBuilder.ScriptSortType.NUMBER).order(SortOrder.DESC);
+
+
+    public ScriptSortBuilder fastDefaultSort() {
+        Map<String, Object> params = new HashMap<>();
+        String script_inline =
+                "if(doc['cname.value.keyword'].value==null||doc['cname.value.keyword'].value.length()<=3){" +
+                        "return 0.3;" +
+                        "}" +
+                        "if(doc['reg_status'].value==null || doc['reg_status'].value.contains('销')){" +
+                        "return 1;" +
+                        "}" +
+                        "double a = doc['reg_capital_amount']==null?0.0:doc['reg_capital_amount'].value>1000000000000.0?1000000000000.0:doc['reg_capital_amount'].value;" +
+                        "double w = Math.log(a/10000000+1)+1;" +
+                        "if(doc['company_type'].value=='1'){" +
+                        "w=w+3;" +
+                        "}" +
+                        "return w;";
+
+        Script script = new Script(ScriptType.INLINE, "painless", script_inline, params);
+        return new ScriptSortBuilder(script, ScriptSortBuilder.ScriptSortType.NUMBER).order(SortOrder.DESC);
+
+    }
+
+    public ScriptSortBuilder defaultSort() {
+        Map<String, Object> params = new HashMap(12) {
+            {
+                put("xjk_company", "test");
+            }
+        };
+
+        String script_inline = "if(doc['reg_status'].value==null || doc['reg_status'].value.contains('销')){        " +
+                "return _score;  " +
+                "}" +
+                "double w = 1;" +
+                "        if(doc['reg_capital_amount'].value!=null){" +
+                "          w = Math.log(doc['reg_capital_amount'].value/10000000+1)+1;" +
+                "        }" +
+                "         if(doc['company_type'].value=='1'){" +
+                "              w = w+3;" +
+                "            }" +
+                "double s = _score;" +
+                "              if(doc['cname.value.keyword'].value==null||doc['cname.value.keyword'].value.length()<=3){" +
+                "                s = Math.log(s+1);" +
+                "              }" +
+                "          return s*w;" +
+                "";
+
+        Script script = new Script(ScriptType.INLINE, "painless", script_inline, params);
+        return new ScriptSortBuilder(script, ScriptSortBuilder.ScriptSortType.NUMBER).order(SortOrder.DESC);
+    }
+
+
+    public ScriptSortBuilder functionSort() {
+        Map<String, Object> params = new HashMap<>();
+        String inlineScript = "double s=doc['reg_capital_amount']==null?0.0:doc['reg_capital_amount'].value/100;double t=doc['estiblish_time']==null?0:doc['estiblish_time'].value;s=s>10000000000.0?10000000000.0:s;return (s/10000000+t/31536000000.0*2);";
+        Script script = new Script(ScriptType.INLINE, "painless", inlineScript, params);
+        return new ScriptSortBuilder(script, ScriptSortBuilder.ScriptSortType.NUMBER).order(SortOrder.DESC);
+    }
+}

+ 26 - 0
src/main/java/com/winhc/phoenix/example/vo/SmsBean.java

@@ -0,0 +1,26 @@
+package com.winhc.phoenix.example.vo;
+
+import com.winhc.phoenix.example.util.JsonUtils;
+import lombok.Getter;
+
+import java.io.Serializable;
+
+/**
+ * @author: XuJiakai
+ * 2020/10/30 17:07
+ */
+@Getter
+public class SmsBean implements Serializable {
+    public SmsBean(String[] mobileNo, String content) {
+        this.mobileNo = mobileNo;
+        this.content = content;
+    }
+
+    private String[] mobileNo;
+    private String content;
+
+    @Override
+    public String toString() {
+        return JsonUtils.jsonObjToString(this);
+    }
+}

+ 105 - 0
src/main/java/org/elasticsearch/common/text/Text.java

@@ -0,0 +1,105 @@
+package org.elasticsearch.common.text;
+
+
+
+import org.elasticsearch.common.bytes.BytesArray;
+import org.elasticsearch.common.bytes.BytesReference;
+
+import java.io.Serializable;
+import java.nio.charset.StandardCharsets;
+
+/**
+ * Both {@link String} and {@link BytesReference} representation of the text. Starts with one of those, and if
+ * the other is requests, caches the other one in a local reference so no additional conversion will be needed.
+ */
+/**
+ * @author: XuJiakai
+ * 2020/11/24 09:29
+ */
+public final class Text implements Comparable<Text>, Serializable {
+
+    public static final Text[] EMPTY_ARRAY = new Text[0];
+
+    public static Text[] convertFromStringArray(String[] strings) {
+        if (strings.length == 0) {
+            return EMPTY_ARRAY;
+        }
+        Text[] texts = new Text[strings.length];
+        for (int i = 0; i < strings.length; i++) {
+            texts[i] = new Text(strings[i]);
+        }
+        return texts;
+    }
+
+    private BytesReference bytes;
+    private String text;
+    private int hash;
+
+    public Text(BytesReference bytes) {
+        this.bytes = bytes;
+    }
+
+    public Text(String text) {
+        this.text = text;
+    }
+
+    /**
+     * Whether a {@link BytesReference} view of the data is already materialized.
+     */
+    public boolean hasBytes() {
+        return bytes != null;
+    }
+
+    /**
+     * Returns a {@link BytesReference} view of the data.
+     */
+    public BytesReference bytes() {
+        if (bytes == null) {
+            bytes = new BytesArray(text.getBytes(StandardCharsets.UTF_8));
+        }
+        return bytes;
+    }
+
+    /**
+     * Whether a {@link String} view of the data is already materialized.
+     */
+    public boolean hasString() {
+        return text != null;
+    }
+
+    /**
+     * Returns a {@link String} view of the data.
+     */
+    public String string() {
+        return text == null ? bytes.utf8ToString() : text;
+    }
+
+    @Override
+    public String toString() {
+        return string();
+    }
+
+    @Override
+    public int hashCode() {
+        if (hash == 0) {
+            hash = bytes().hashCode();
+        }
+        return hash;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null || getClass() != obj.getClass()) {
+            return false;
+        }
+        return bytes().equals(((Text) obj).bytes());
+    }
+
+    @Override
+    public int compareTo(Text text) {
+        return bytes().compareTo(text.bytes());
+    }
+}

+ 128 - 0
src/main/java/org/elasticsearch/script/ScriptType.java

@@ -0,0 +1,128 @@
+package org.elasticsearch.script;
+
+
+import org.elasticsearch.common.ParseField;
+import org.elasticsearch.common.io.stream.StreamInput;
+import org.elasticsearch.common.io.stream.StreamOutput;
+import org.elasticsearch.common.io.stream.Writeable;
+
+import java.io.IOException;
+import java.util.Locale;
+
+/**
+ * ScriptType represents the way a script is stored and retrieved from the {@link ScriptService}.
+ * It's also used to by {@link ScriptSettings} and {@link ScriptModes} to determine whether or not
+ * a {@link Script} is allowed to be executed based on both default and user-defined settings.
+ */
+/**
+ * @author: XuJiakai
+ * 2020/11/20 16:57
+ */
+
+public enum ScriptType implements Writeable {
+
+    /**
+     * INLINE scripts are specified in numerous queries and compiled on-the-fly.
+     * They will be cached based on the lang and code of the script.
+     * They are turned off by default because most languages are insecure
+     * (Groovy and others), but can be overriden by the specific {@link ScriptEngineService}
+     * if the language is naturally secure (Painless, Mustache, and Expressions).
+     */
+    INLINE ( 0 , new ParseField("inline", "inline") , false ),
+
+    /**
+     * STORED scripts are saved as part of the {@link org.elasticsearch.cluster.ClusterState}
+     * based on user requests.  They will be cached when they are first used in a query.
+     * They are turned off by default because most languages are insecure
+     * (Groovy and others), but can be overriden by the specific {@link ScriptEngineService}
+     * if the language is naturally secure (Painless, Mustache, and Expressions).
+     */
+    STORED ( 1 , new ParseField("id", "stored") , false ),
+
+    /**
+     * FILE scripts are loaded from disk either on start-up or on-the-fly depending on
+     * user-defined settings.  They will be compiled and cached as soon as they are loaded
+     * from disk.  They are turned on by default as they should always be safe to execute.
+     */
+    FILE ( 2 , new ParseField("file") , true  );
+
+    /**
+     * Reads an int from the input stream and converts it to a {@link ScriptType}.
+     * @return The ScriptType read from the stream. Throws an {@link IllegalStateException}
+     * if no ScriptType is found based on the id.
+     */
+    public static ScriptType readFrom(StreamInput in) throws IOException {
+        int id = in.readVInt();
+
+        if (FILE.id == id) {
+            return FILE;
+        } else if (STORED.id == id) {
+            return STORED;
+        } else if (INLINE.id == id) {
+            return INLINE;
+        } else {
+            throw new IllegalStateException("Error reading ScriptType id [" + id + "] from stream, expected one of [" +
+                    FILE.id + " [" + FILE.parseField.getPreferredName() + "], " +
+                    STORED.id + " [" + STORED.parseField.getPreferredName() + "], " +
+                    INLINE.id + " [" + INLINE.parseField.getPreferredName() + "]]");
+        }
+    }
+
+    private final int id;
+    private final ParseField parseField;
+    private final boolean defaultEnabled;
+
+    /**
+     * Standard constructor.
+     * @param id A unique identifier for a type that can be read/written to a stream.
+     * @param parseField Specifies the name used to parse input from queries.
+     * @param defaultEnabled Whether or not a {@link ScriptType} can be run by default.
+     */
+    ScriptType(int id, ParseField parseField, boolean defaultEnabled) {
+        this.id = id;
+        this.parseField = parseField;
+        this.defaultEnabled = defaultEnabled;
+    }
+
+    public void writeTo(StreamOutput out) throws IOException {
+        out.writeVInt(id);
+    }
+
+    /**
+     * @return The unique id for this {@link ScriptType}.
+     */
+    public int getId() {
+        return id;
+    }
+
+    /**
+     * @return The unique name for this {@link ScriptType} based on the {@link ParseField}.
+     */
+    public String getName() {
+        return name().toLowerCase(Locale.ROOT);
+    }
+
+    /**
+     * @return Specifies the name used to parse input from queries.
+     */
+    public ParseField getParseField() {
+        return parseField;
+    }
+
+    /**
+     * @return Whether or not a {@link ScriptType} can be run by default.  Note
+     * this can be potentially overriden by any {@link ScriptEngineService}.
+     */
+    public boolean isDefaultEnabled() {
+        return defaultEnabled;
+    }
+
+    /**
+     * @return The same as calling {@link #getName()}.
+     */
+    @Override
+    public String toString() {
+        return getName();
+    }
+}
+

+ 9 - 0
src/main/resources/application.yml

@@ -24,6 +24,10 @@ spring:
   data:
     mongodb:
       uri: mongodb://itslaw:itslaw_168@dds-uf6ff5dfd9aef3641601-pub.mongodb.rds.aliyuncs.com:3717,dds-uf6ff5dfd9aef3642555-pub.mongodb.rds.aliyuncs.com:3717/itslaw?replicaSet=mgset-6501997
+es:
+  username: elastic
+  password: elastic_168
+  host: es-cn-0pp0r32zf000ipovd.public.elasticsearch.aliyuncs.com
 
 hbase:
   config:
@@ -37,6 +41,11 @@ spring:
       server:
         url: http://hb-uf6m8e1nu4ivp06m5-proxy-phoenix.hbase.rds.aliyuncs.com:8765
 
+es:
+  username: elastic
+  password: elastic_168
+  host: es-cn-0pp0r32zf000ipovd.elasticsearch.aliyuncs.com
+
 hbase:
   config:
     hbase.zookeeper.quorum: hb-uf6m8e1nu4ivp06m5-master1-001.hbase.rds.aliyuncs.com:2181,hb-uf6m8e1nu4ivp06m5-master2-001.hbase.rds.aliyuncs.com:2181,hb-uf6m8e1nu4ivp06m5-master3-001.hbase.rds.aliyuncs.com:2181