需求分析
1.实现大数据量(大于千万)环境下,具有【多字段】、【快速】、【支持模糊匹配和拆词】的**检索功能的小程序。
2.数据环境:阿里云ES、阿里云MySQL
3.项目部署:阿里云服务器
实现(部分)
首先:强调一下,一定要关注阿里云的ES文档!
连接阿里云文档
特别注意:
ES官方已不建议通过TransportClient来访问Elasticsearch,使用TransportClient 5.5.3版在建立连接时会报 NoNodeAvailableException 问题,并且ES官方已经不再维护TransportClient。如果已经使用并且有提示报错,可用以下方法绕过:
建议换成Java Low Level REST Client来访问Elasticsearch。
在Java maven项目的POM配置文件中,使用 x-pack-transport-5.3.3 版client进行访问,并且POM配置文件中的elasticsearch版本也必须为5.3.3版,不建议通过该方案来绕着实现,不保证能完全兼容。
温馨提示:
由于阿里云Elasticsearch实例使用5.5.3版本,所以需要您的JDK至少在 1.8 及以上版本。
更多语言demo,详情请求参见 HTTP/REST Clients and Security。
我就是因为本机测试安装的是最新版本ES6.3.1版本,应用TransportClient查询,结果给自己弄坑里了,报:no node available 别找我哈
代码部分
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.entity.ContentType;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
import org.apache.http.nio.entity.NStringEntity;
import org.apache.http.util.EntityUtils;
import org.elasticsearch.client.Response;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import java.io.IOException;
import java.util.Collections;
/**
*参数说明:
*<USER NAME>:替换为访问阿里云ES实例对应用户名。
*<PASSWORD>:替换为访问阿里云ES实例指定用户对应密码。
*<HOST>:替换为阿里云ES实例基本信息界面中的内网或外网地址。
*/
public class RestClientTest {
public static void main(String[]args){
final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY,
new UsernamePasswordCredentials("<USER NAME>", "<PASSWORD>"));
RestClient restClient = RestClient.builder(new HttpHost("<HOST>", 9200))
.setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
@Override
public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {
return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
}
}).build();
try {
//index a document
HttpEntity entity = new NStringEntity("{\n\"user\" : \"kimchy\"\n}", ContentType.APPLICATION_JSON);
Response indexResponse = restClient.performRequest(
"PUT",
"/index/type/123",
Collections.<String, String>emptyMap(),
entity);
//search a document
Response response = restClient.performRequest("GET", "/index/type/123",
Collections.singletonMap("pretty", "true"));
System.out.println(EntityUtils.toString(response.getEntity()));
} catch (IOException e) {
e.printStackTrace();
}
}
}
应用代码
代码粘过去没用,仅供参考
@RequestMapping("/query")
public ServiceResult queryPage(@RequestParam("reqParam") String reqParam, @RequestParam("page") String page,@RequestParam("pageSize") String pageSize) {
ServiceResult result = new ServiceResult();
Map<String,Object> map = new HashMap<>();//用于封装返回结果
HttpEntity entity = new NStringEntity("{\n" +
" \"query\": {\n" +
" \"multi_match\" : {\n" +
" \"query\": \""+reqParam+"\", \n" +
" \"fields\": [ \"title\", \"applicantZh\" ,\"applicantEn\",\"number\"] \n" +
" }\n" +
" }\n" +
"}", ContentType.APPLICATION_JSON);
try {
int from = (Integer.valueOf(page) - 1) * Integer.valueOf(pageSize);
String endpoint = "/_search?size=" + pageSize + "&from=" + from;
Response response = esClient.performRequest("GET",
endpoint,
Collections.emptyMap(),
entity);
//TODO 针对response进行你需要的操作
return result;
}
ok,暂时这样吧,共同进步^_^