学习目标
理解ES的搜索解决方案和能力
掌握ES各种搜索类型和使用方式
Elastic search是目前业界最主流的分布式搜索引擎,没有之一
目录
Elastic Search 索引和文档的操作方式 es构建索引(lucene相对底层)
使用Elastic Search搜索
Elastic Search索引和文档的操作方式 创建索引 kibana 简单,可视化,开发调试方便
同步索引数据
基于Kibana同步索引数据 开发调试使用
基于Logstash同步索引数据 -般场景同步,定时任务执行脚本,控制力很弱(不好改)
基于客户端API同步索引数据 业务系统数据双写
kibana Logstash 使用logstash-input-jdbc插件,同步支持jdbc规范的数据源(如mysql) 缺点:脚本可能需要处理业务逻辑,边界不清晰
控制输入1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 input { jdbc { # 数据库 jdbc_connection_string =>"jdbc:mysql://localhost:3306/customer_system" # 用户名密码 jdbc_user => "root"jdbc password => "root" # jar包的位置 jdbc_driver_library =>"./mysql-connector-java-8.0.28.jar' #mysql的Driver jdbc_driver_class =>"com.mysql.jdbc.Driver" #读取这个 sqlstatement_filepath =>"/mysql2es.sql" #每隔10分钟执行一次 schedule =>*/10 * * * * ... } } output { # index 索引名 index => customer_auto_reply_index # 类似主键,es中id对应数据库的字段 document_id =>"%{id}' stdout { codec => json lines } }
stdout打印输出
Elastic Search客户端
原生es客户端
其他-Spring Data ES客户端
原生es客户端 1 2 3 <dependency> <groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-high-level-client</artifactId> </dependency>
配置信息
1 2 3 4 5 6 7 8 9 elasticsearch: info: username:elastic password: 123456 hostname: localhost port:9200 scheme: http index: customerAutoReplyIndex:customer auto reply_index
配置类
1 2 3 4 5 6 7 8 9 @RefreshScope @configurationProperties(prefix="'elasticsearch.info"") public class EsInfoconfig { private String username; private String password; private String hostname; private int port; private String scheme; }
客户端类
1 2 3 4 5 6 7 8 public class EsClient { private final EsInfoconfig esInfoConfig; @Bean public RestHighLevelclient restHighLevelclient(){ RestClientBuilder builder= RestClient.builder(new HttpHost(esInfoConfig.getHostname(),esInfoConfig.getPort(),esInfoconfig.getscheme())); CredentialsProvider credentialsProvider = new BasicCredentialsProvider(); credentialsProvider.setCredentials(AuthScope.ANY, newUsernamePasswordCredentials(esInfoConfig.getUsername(),esInfoConfig.getPassword())); builder,setHttpclientconfigcallback(f -> f.setDefaultCredentialsProvider(credentialsProvider));return new RestHighLevelclient(builder);
同步数据
1 2 3 4 5 6 7 8 //新增文档 IndexResponse response = client,index(request, RequestOptions.DEFAULT); //批量新增文档 BulkResponse response = restHighLevelclient,.bulk(request, RequestOptions.DEFAULT); //更新文档 UpdateResponse response = restHighLevelclient.update(request,RequestOptions.DEFAULT); //根据查询删除文档 restHighLevelclient,deleteByQuery(request, RequestOptions.DEFAULT);
利用Elastic Search执行搜索 构建搜索对象 SearchRequest:搜索对象 SearchSourceBuilder:搜索条件构建器 BoolQueryBuilder:布尔查询构建器,组合多个查询 QueryBuilders:查询构建器列表 XXXBuilder:具体构建器 HighlightBuilder:高亮构建器 from/size:分页搜索支持
创建搜索条件
Term(项)搜索:不执行分析(不分词) termQuery单字段搜索 wildcardQuery通配符搜索 fuzzyQuery模糊搜索 prefixQuery字符串前缀搜索
全文搜索:执行分析(对字段进行分词处理,并依次匹配多个字段可以在重点字段上设置权重(boost)) matchQuery单字段匹配搜索 multiMatchQuery多字段匹配搜索 matchPharseQuery词组匹配搜索
获取搜索结果 1 2 3 4 5 6 7 8 //1,发起搜素请求并获取结果 SearchResponse = esclient,search(searchRequest, EsConfig.COMMON_OPTIONS); //2,获取匹配的数据 Searchifits hits = response.getHits(); //3,解析结果数据并包装成业务对象 for(SearchHit hit:hits){ Map<String,0bject> result = hit.getSourceAsMap(); }
辅助搜索功能 1 2 3 4 5 6 7 8 9 10 11 SearchRequest searchRequest=.. SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); searchSourceBuilder.query(new TermQueryBuilder("city","Hangzhou")); //指定返回的字段 searchSourceBuilder,fetchSource(new Stringil{"title","city"} , null); searchRequest.source(searchSourceBuilder); //结果计数 CountRequest countRequest = new CountRequest("notel");countRequest.source(searchSourceBuilder); CountResponse countResponse = client.count(countRequest,RequestOptions.DEFAULT); //结果分页 searchSourceBuilder.from(20)searchSourceBuilder.size(10);searchRequest.source(searchSourceBuilder);
DSL DSL(Domain Specific Language,领域特定语言)查询,是ES提出的基于JSON的搜索方式,在搜素时传入特定的JSON格式数据完成不同需求的搜索,通常可以和Kibana配合使用进行开发和调试。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 //查询全部 { "query" :{"match_all":{}} } //分页查询全部 { "from" : "size": "query" :{"'match_all":{}} } //项查询 { "query":{ "term":{ "title”:“开发” } } } //全文多字段匹配查询 "query":{ "multi match":{ "query" : "Java" "fields" : ["title","content"], "minimum_should_match":"50%" } }
示例 配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 # application.yaml elasticsearch: info: username: elastic password: changeme hostname: localhost port: 9200 scheme: http index: customerAutoReplyIndex: customer_auto_reply_index # classes @Data @Component @RefreshScope @ConfigurationProperties(prefix = "elasticsearch.index") public class EsIndexProerties { /** * 客服自动回复索引 */ private String customerAutoReplyIndex; } @Data @Component @RefreshScope @ConfigurationProperties(prefix = "elasticsearch.info") public class EsInfoConfig { private String username; private String password; private String hostname; private int port; private String scheme; }
依赖
1 2 3 4 5 6 7 8 9 10 11 12 <dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>elasticsearch-rest-high-level-client</artifactId> </dependency> <dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>elasticsearch-rest-client</artifactId> </dependency> <dependency> <groupId>org.elasticsearch</groupId> <artifactId>elasticsearch</artifactId> </dependency>
客户端
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 @Configuration @RequiredArgsConstructor public class EsClient { private final EsInfoConfig esInfoConfig; @Bean public RestHighLevelClient restHighLevelClient() { RestClientBuilder builder = RestClient.builder(new HttpHost(esInfoConfig.getHostname(), esInfoConfig.getPort(), esInfoConfig.getScheme())); CredentialsProvider credentialsProvider = new BasicCredentialsProvider(); credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(esInfoConfig.getUsername(), esInfoConfig.getPassword())); builder.setHttpClientConfigCallback(f -> f.setDefaultCredentialsProvider(credentialsProvider)); return new RestHighLevelClient(builder); } }
思考题 想搜索和全文搜索的区别?