创建搜索工程创建搜索工程(尘补惫别苍工程):虫肠-蝉别谤惫颈肠别-蝉别补谤肠丑,添加搁别蝉迟贬颈驳丑尝别惫别濒颁濒颈别苍迟依赖及箩耻苍颈迟依赖。辫辞尘.虫尘濒 xc-framework-parent com.xuecheng 1.0-SNAPSHOT ../xc-framework-parent/pom.xml 4.0.0 xc-service-search com.xuecheng xc-framework-model 1.0-SNAPSHOT com.xuecheng xc-framework-common 1.0-SNAPSHOT com.xuecheng xc-service-api 1.0-SNAPSHOT org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-web org.elasticsearch.client elasticsearch-rest-high-level-client 6.2.1 org.elasticsearch elasticsearch 6.2.1 org.springframework.boot spring-boot-starter-test test com.alibaba fastjson org.apache.commons commons-io org.apache.commons commons-lang3 2、配置文件application.ymlserver: port: ${port:40100}spring: application: name: xc-search-servicexuecheng: elasticsearch: hostlist: ${eshostlist:127.0.0.1:9200} #多个结点中间用逗号分隔3、配置类创建com.xuecheng.search.config包在其下创建配置类package com.xuecheng.search.config;import org.apache.http.HttpHost;import org.elasticsearch.client.RestClient;import org.elasticsearch.client.RestHighLevelClient;import org.springframework.beans.factory.annotation.Value;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;@Configurationpublic class ElasticsearchConfig { @Value("${xuecheng.elasticsearch.hostlist}") private String hostlist; @Bean public RestHighLevelClient restHighLevelClient(){ //解析hostlist配置信息 String[] split = hostlist.split(","); //创建HttpHost数组,其中存放es主机和端口的配置信息 HttpHost[] httpHostArray = new HttpHost[split.length]; for(int i=0;i jsonMap = new HashMap<>(); jsonMap.put("name", "spring cloud实战"); jsonMap.put("description", "本课程主要从四个章节进行讲解: 1.微服务架构入门 2.spring cloud 基础入门 3.实战Spring Boot 4.注册中心eureka。"); jsonMap.put("studymodel", "201001"); SimpleDateFormat dateFormat =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); jsonMap.put("timestamp", dateFormat.format(new Date())); jsonMap.put("price", 5.6f); //索引请求对象 IndexRequest indexRequest = new IndexRequest("xc_course","doc"); //指定索引文档内容 indexRequest.source(jsonMap); //索引响应对象 IndexResponse indexResponse = client.index(indexRequest); //获取响应结果 DocWriteResponse.Result result = indexResponse.getResult(); System.out.println(result); }查询文档API格式如下: GET /{index}/{type}/{id}Java Client//查询文档@Testpublic void getDoc() throws IOException { GetRequest getRequest = new GetRequest( "xc_course", "doc", "4028e581617f945f01617f9dabc40000"); GetResponse getResponse = client.get(getRequest); boolean exists = getResponse.isExists(); Map sourceAsMap = getResponse.getSourceAsMap(); System.out.println(sourceAsMap);}更新文档ApiES更新文档的顺序是:先检索到文档、将原来的文档标记为删除、创建新文档、删除旧文档,创建新文档就会重建索引。通过请求Url有两种方法:1、完全替换Post:http://localhost:9200/xc_test/doc/3 { "name":"spring cloud实战", "description":"本课程主要从四个章节进行讲解: 1.微服务架构入门 2.spring cloud 基础入门 3.实战Spring Boot 4.注册中心eureka。", "studymodel":"201001" "price":5.6 }2、局部更新下边的例子是只更新price字段。post: http://localhost:9200/xc_test/doc/3/_update{ "doc":{"price":66.6}}Java Client使用 Client Api更新文档的方法同上边第二种局部更新方法。可以指定文档的部分字段也可以指定完整的文档内容。 //更新文档 @Test public void updateDoc() throws IOException { UpdateRequest updateRequest = new UpdateRequest("xc_course", "doc", "4028e581617f945f01617f9dabc40000"); Map map = new HashMap<>(); map.put("name", "spring cloud实战"); updateRequest.doc(map); UpdateResponse update = client.update(updateRequest); RestStatus status = update.status(); System.out.println(status); }删除文档Api根据id删除,格式如下:DELETE /{index}/{type}/{id}搜索匹配删除,将搜索出来的记录删除,格式如下:POST /{index}/{type}/_delete_by_query下边是搜索条件例子:{ "query":{ "term":{ "studymodel":"201001" } }}上边例子的搜索匹配删除会将studymodel为201001的记录全部删除。Java Client//根据id删除文档 @Test public void testDelDoc() throws IOException { //删除文档id String id = "eqP_amQBKsGOdwJ4fHiC"; //删除索引请求对象 DeleteRequest deleteRequest = new DeleteRequest("xc_course","doc",id); //响应对象 DeleteResponse deleteResponse = client.delete(deleteRequest); //获取响应结果 DocWriteResponse.Result result = deleteResponse.getResult(); System.out.println(result); }搜索匹配删除还没有具体的api,可以采用先搜索出文档id,根据文档id删除。搜索管理准备环境创建映射创建xc_course索引库。创建如下映射post:http://localhost:9200/xc_course/doc/_mapping参考 “资料”--》搜索测试-初始化数据.txt{ "properties": { "description": { "type": "text", "analyzer": "ik_max_word", "search_analyzer": "ik_smart" }, "name": { "type": "text", "analyzer": "ik_max_word", "search_analyzer": "ik_smart" }, "pic":{ "type":"text", "index":false }, "price": { "type": "float" }, "studymodel": { "type": "keyword" }, "timestamp": { "type": "date", "format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis" } } }插入原始数据向xc_course/doc中插入以下数据:参考 “资料”--》搜索测试-初始化数据.txthttp://localhost:9200/xc_course/doc/1{"name": "Bootstrap开发","description": "Bootstrap是由Twitter推出的一个前台页面开发css框架,是一个非常流行的开发框架,此框架集成了多种页面效果。此开发框架包含了大量的CSS、JS程序代码,可以帮助开发者(尤其是不擅长css页面开发的程序人员)轻松的实现一个css,不受浏览器限制的精美界面css效果。","studymodel": "201002","price":38.6,"timestamp":"2018-04-25 19:11:35","pic":"group1/M00/00/00/wKhlQFs6RCeAY0pHAAJx5ZjNDEM428.jpg"}http://localhost:9200/xc_course/doc/2{"name": "java编程基础","description": "java语言是世界第一编程语言,在软件开发领域使用人数最多。","studymodel": "201001","price":68.6,"timestamp":"2018-03-25 19:11:35","pic":"group1/M00/00/00/wKhlQFs6RCeAY0pHAAJx5ZjNDEM428.jpg"}http://localhost:9200/xc_course/doc/3{"name": "spring开发基础","description": "spring 在java领域非常流行,java程序员都在用。","studymodel": "201001","price":88.6,"timestamp":"2018-02-24 19:11:35","pic":"group1/M00/00/00/wKhlQFs6RCeAY0pHAAJx5ZjNDEM428.jpg"}简单搜索简单搜索就是通过url进行查询,以get方式请求ES。格式:get ../_search?q=.....q:搜索字符串。例子:?q=name:spring 搜索name中包括spring的文档。DSL搜索DSL(Domain Specific Language)是ES提出的基于json的搜索方式,在搜索时传入特定的json格式的数据来完成不同的搜索需求。DSL比URI搜索方式功能强大,在项目中建议使用DSL方式来完成搜索。查询所有文档查询所有索引库的文档。发送:post http://localhost:9200/_search查询指定索引库指定类型下的文档。(通过使用此方法)发送:post http://localhost:9200/xc_course/doc/_search{ "query": { "match_all": {} }, "_source" : ["name","studymodel"]}_source:source源过虑设置,指定结果中所包括的字段有哪些。结果说明:took:本次操作花费的时间,单位为毫秒。timed_out:请求是否超时_shards:说明本次操作共搜索了哪些分片hits:搜索命中的记录hits.total : 符合条件的文档总数 hits.hits :匹配度较高的前N个文档hits.max_score:文档匹配得分,这里为最高分_score:每个文档都有一个匹配度得分,按照降序排列。_source:显示了文档的原始内容。JavaClient:@SpringBootTest@RunWith(SpringRunner.class)public class TestSearch { @Autowired RestHighLevelClient client; @Autowired RestClient restClient; //搜索type下的全部记录 @Test public void testSearchAll() throws IOException, ParseException { //搜索请求对象 SearchRequest searchRequest = new SearchRequest("xc_course"); //设置类型 searchRequest.types("doc"); //搜索源构建对象 SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); //搜索全部 searchSourceBuilder.query(QueryBuilders.matchAllQuery()); //source源字段过虑 searchSourceBuilder.fetchSource(new String[]{"name","studymodel","price","timestamp"},new String[]{}); //设置搜索源 searchRequest.source(searchSourceBuilder); //执行搜索 SearchResponse searchResponse = client.search(searchRequest); //搜索匹配结果 SearchHits hits = searchResponse.getHits(); //搜索总记录数 long totalHits = hits.totalHits; //匹配度较高的前N个文档 SearchHit[] searchHits = hits.getHits(); //日期格式化对象 SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); for(SearchHit hit:searchHits){ //文档id String id = hit.getId(); //源文档内容 Map sourceAsMap = hit.getSourceAsMap(); //获取源文档name String name = (String) sourceAsMap.get("name"); String description = (String) sourceAsMap.get("description"); String studymodel = (String) sourceAsMap.get("studymodel"); Double price = (Double) sourceAsMap.get("price"); Date timestamp = dateFormat.parse((String) sourceAsMap.get("timestamp")); System.out.println(name); System.out.println(studymodel); System.out.println(description); } } ....分页查询ES支持分页查询,传入两个参数:from和size。form:表示起始文档的下标,从0开始。size:查询的文档数量。发送:post http://localhost:9200/xc_course/doc/_search{"from" : 0, "size" : 1,"query": { "match_all": {} },"_source" : ["name","studymodel"]}JavaClient...SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();//设置分页参数//当前页码int page = 2;//页码int size = 1;//每页显示个数int from = (page - 1) * size;//起记录下标searchSourceBuilder.from(from);searchSourceBuilder.size(size);...Term QueryTerm Query为精确查询,在搜索时会整体匹配关键字,不再将关键字分词。发送:post http://localhost:9200/xc_course/doc/_search{ "query": { "term" : { "name": "spring" } }, "_source" : ["name","studymodel"] }上边的搜索会查询name包括“spring”这个词的文档。JavaClient:...//搜索请求对象SearchRequest searchRequest = new SearchRequest("xc_course");//设置类型searchRequest.types("doc");//搜索源构建对象SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();//TermQuerysearchSourceBuilder.query(QueryBuilders.termQuery("name","spring"));//source源字段过虑searchSourceBuilder.fetchSource(new String[]{"name","studymodel","price","timestamp"},new String[]{});//设置搜索源searchRequest.source(searchSourceBuilder);//执行搜索SearchResponse searchResponse = client.search(searchRequest);...根据id精确匹配ES提供根据多个id值匹配的方法:测试:post: http://127.0.0.1:9200/xc_course/doc/_search{ "query": { "ids" : { "type" : "doc", "values" : ["3", "4", "100"] } }}JavaClient:通过termsQuery进行查询,代码如下://搜索请求对象SearchRequest searchRequest = new SearchRequest("xc_course");//设置类型searchRequest.types("doc");//搜索源构建对象SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();//主键String[] ids = new String[]{"1","2"};//TermQuerysearchSourceBuilder.query(QueryBuilders.termsQuery("_id", ids));//source源字段过虑searchSourceBuilder.fetchSource(new String[]{"name","studymodel","price","timestamp"},new String[]{});//设置搜索源searchRequest.source(searchSourceBuilder);//执行搜索SearchResponse searchResponse = client.search(searchRequest);match Query1、基本使用match Query即全文检索,它的搜索方式是先将搜索字符串分词,再使用各各词条从索引中搜索。match query与Term query区别是match query在搜索前先将搜索关键字分词,再拿各各词语去索引中搜索。发送:post http://localhost:9200/xc_course/doc/_search{ "query": { "match" : { "description" : { "query" : "spring开发", "operator" : "or" } } }}query:搜索的关键字,对于英文关键字如果有多个单词则中间要用半角逗号分隔,而对于中文关键字中间可以用逗号分隔也可以不用。operator:or 表示 只要有一个词在文档中出现则就符合条件,and表示每个词都在文档中出现则才符合条件。上边的搜索的执行过程是:1、将“spring开发”分词,分为spring、开发两个词2、再使用spring和开发两个词去匹配索引中搜索。3、由于设置了operator为or,只要有一个词匹配成功则就返回该文档。JavaClient://根据关键字搜索@Test public void testMatchQuery() throws IOException, ParseException { //搜索请求对象 SearchRequest searchRequest = new SearchRequest("xc_course"); //设置类型 searchRequest.types("doc"); //搜索源构建对象 SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); //MatcherQuery searchSourceBuilder.query(QueryBuilders.matchQuery("description","spring开发").operator(Operator.OR)); //source源字段过虑 searchSourceBuilder.fetchSource(new String[]{"name","studymodel","price","timestamp"},new String[]{}); //设置搜索源 searchRequest.source(searchSourceBuilder); //执行搜索 SearchResponse searchResponse = client.search(searchRequest); //搜索匹配结果 SearchHits hits = searchResponse.getHits(); //搜索总记录数 long totalHits = hits.totalHits; //匹配度较高的前N个文档 SearchHit[] searchHits = hits.getHits(); //日期格式化对象 SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); for(SearchHit hit:searchHits){ //文档id String id = hit.getId(); //源文档内容 Map sourceAsMap = hit.getSourceAsMap(); //获取源文档name String name = (String) sourceAsMap.get("name"); String description = (String) sourceAsMap.get("description"); String studymodel = (String) sourceAsMap.get("studymodel"); Double price = (Double) sourceAsMap.get("price"); Date timestamp = dateFormat.parse((String) sourceAsMap.get("timestamp")); System.out.println(name); System.out.println(studymodel); System.out.println(description); } }2、minimum_should_match上边使用的operator = or表示只要有一个词匹配上就得分,如果实现三个词至少有两个词匹配如何实现?使用minimum_should_match可以指定文档匹配词的占比:比如搜索语句如下:{ "query": { "match" : { "description" : { "query" : "spring开发框架", "minimum_should_match": "80%" } } }}“spring开发框架”会被分为三个词:spring、开发、框架设置"minimum_should_match": "80%"表示,三个词在文档的匹配占比为80%,即3*0.8=2.4,向上取整得2,表示至少有两个词在文档中要匹配成功。对应的RestClient如下://MatcherQuery searchSourceBuilder.query(QueryBuilders.matchQuery("description","spring开发框架") .operator(Operator.OR) .minimumShouldMatch("80%")); multi Query上边学习的termQuery和matchQuery一次只能匹配一个Field,本节学习multiQuery,一次可以匹配多个字段。1、基本使用单项匹配是在一个field中去匹配,多项匹配是拿关键字去多个Field中匹配。例子:发送:post http://localhost:9200/xc_course/doc/_search拿关键字 “spring css”去匹配name 和description字段。{ "query": { "multi_match" : { "query" : "spring css", "minimum_should_match": "50%", "fields": [ "name", "description" ] } }}2、提升boost匹配多个字段时可以提升字段的boost(权重)来提高得分例子:提升boost之前,执行下边的查询:{ "query": { "multi_match" : { "query" : "spring css", "minimum_should_match": "50%", "fields": [ "name", "description" ] } }}通过查询发现Bootstrap排在前边。提升boost,通常关键字匹配上name的权重要比匹配上description的权重高,这里可以对name的权重提升。{ "query": { "multi_match" : { "query" : "spring css", "minimum_should_match": "50%", "fields": [ "name^10", "description" ] } }}“name^10” 表示权重提升10倍,执行上边的查询,发现name中包括spring关键字的文档排在前边。JavaClient://搜索源构建对象SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();//MultiMatcherQueryMultiMatchQueryBuilder matchQueryBuilder = QueryBuilders.multiMatchQuery("spring css", "name", "description") .minimumShouldMatch("50%") .field("name", 10);searchSourceBuilder.query(matchQueryBuilder);布尔查询布尔查询对应于Lucene的BooleanQuery查询,实现将多个查询组合起来。三个参数:must:文档必须匹配must所包括的查询条件,相当于 “AND” should:文档应该匹配should所包括的查询条件其中的一个或多个,相当于 "OR" must_not:文档不能匹配must_not所包括的该查询条件,相当于“NOT”分别使用must、should、must_not测试下边的查询:发送:POST http://localhost:9200/xc_course/doc/_search{ "_source" : [ "name", "studymodel", "description"], "from" : 0, "size" : 1, "query": { "bool" : { "must":[ { "multi_match" : { "query" : "spring css", "minimum_should_match": "50%", "fields": [ "name^10", "description" ] } }, { "term":{ "studymodel" : "201001" } } ] } }}must:表示必须,多个查询条件必须都满足。(通常使用must)should:表示或者,多个查询条件只要有一个满足即可。must_not:表示非。JavaClient://BoolQuery,将搜索关键字分词,拿分词去索引库搜索//搜索源构建对象SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();//MultiMatcherQueryMultiMatchQueryBuilder matchQueryBuilder = QueryBuilders.multiMatchQuery("spring css", "name", "description") .minimumShouldMatch("50%") .field("name", 10);//TermQueryTermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("studymodel", "201001");//boolQueryBuilderBoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();//将MultiMatcherQuery和TermQuery组织在一起boolQueryBuilder.must(matchQueryBuilder);boolQueryBuilder.must(termQueryBuilder);searchSourceBuilder.query(boolQueryBuilder);过虑器过虑是针对搜索的结果进行过虑,过虑器主要判断的是文档是否匹配,不去计算和判断文档的匹配度得分,所以过虑器性能比查询要高,且方便缓存,推荐尽量使用过虑器去实现查询或者过虑器和查询共同使用。过虑器在布尔查询中使用,下边是在搜索结果的基础上进行过虑:{ "_source" : [ "name", "studymodel", "description","price"], "query": { "bool" : { "must":[ { "multi_match" : { "query" : "spring css", "minimum_should_match": "50%", "fields": [ "name^10", "description" ] } } ], "filter": [ { "term": { "studymodel": "201001" }}, { "range": { "price": { "gte": 60 ,"lte" : 100}}} ] } }}range:范围过虑,保留大于等于60 并且小于等于100的记录。term:项匹配过虑,保留studymodel等于"201001"的记录。注意:range和term一次只能对一个Field设置范围过虑。client://搜索源构建对象SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();//MultiMatcherQueryMultiMatchQueryBuilder matchQueryBuilder = QueryBuilders.multiMatchQuery("spring css", "name", "description") .minimumShouldMatch("50%") .field("name", 10);//boolQueryBuilderBoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();//将MultiMatcherQuery和TermQuery组织在一起boolQueryBuilder.must(matchQueryBuilder);//添加过虑器//项过虑boolQueryBuilder.filter(QueryBuilders.termQuery("studymodel","201001"));//范围过虑boolQueryBuilder.filter(QueryBuilders.rangeQuery("price").gte(60).lte(100));searchSourceBuilder.query(boolQueryBuilder);排序可以在字段上添加一个或多个排序,支持在keyword、date、float等类型上添加,text类型的字段上不允许添加排序。发送 POST http://localhost:9200/xc_course/doc/_search过虑0--10元价格范围的文档,并且对结果进行排序,先按studymodel降序,再按价格升序{ "_source" : [ "name", "studymodel", "description","price"], "query": { "bool" : { "filter": [ { "range": { "price": { "gte": 0 ,"lte" : 100}}} ] } }, "sort" : [ { "studymodel" : "desc" }, { "price" : "asc" } ]}client:@Testpublic void testSort() throws IOException, ParseException { //搜索请求对象 SearchRequest searchRequest = new SearchRequest("xc_course"); //设置类型 searchRequest.types("doc"); //搜索源构建对象 SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); //source源字段过虑 searchSourceBuilder.fetchSource(new String[]{"name","studymodel","price","timestamp"},new String[]{}); //boolQueryBuilder BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery(); //添加过虑器 //范围过虑 boolQueryBuilder.filter(QueryBuilders.rangeQuery("price").gte(0).lte(100)); searchSourceBuilder.query(boolQueryBuilder); //设置搜索源 searchRequest.source(searchSourceBuilder); //设置排序 searchSourceBuilder.sort("studymodel", SortOrder.DESC); searchSourceBuilder.sort("price", SortOrder.ASC); //执行搜索 SearchResponse searchResponse = client.search(searchRequest); //搜索匹配结果 SearchHits hits = searchResponse.getHits(); //搜索总记录数 long totalHits = hits.totalHits; //匹配度较高的前N个文档 SearchHit[] searchHits = hits.getHits(); //日期格式化对象 SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); for(SearchHit hit:searchHits){ //文档id String id = hit.getId(); //源文档内容 Map sourceAsMap = hit.getSourceAsMap(); //获取源文档name String name = (String) sourceAsMap.get("name"); String description = (String) sourceAsMap.get("description"); String studymodel = (String) sourceAsMap.get("studymodel"); Double price = (Double) sourceAsMap.get("price"); Date timestamp = dateFormat.parse((String) sourceAsMap.get("timestamp")); System.out.println(name); System.out.println(studymodel); System.out.println(description); }}高亮显示高亮显示可以将搜索结果一个或多个字突出显示,以便向用户展示匹配关键字的位置。在搜索语句中添加highlight即可实现,如下:Post: http://127.0.0.1:9200/xc_course/doc/_search{ "_source" : [ "name", "studymodel", "timestamp","price"], "query": { "bool" : { "must":[ { "multi_match" : { "query" : "开发框架", "minimum_should_match": "50%", "fields": [ "name^10", "description" ] } } ], "filter": [ { "range": { "price": { "gte": 0 ,"lte" : 100}}} ] } }, "sort" : [ { "price" : "asc" } ], "highlight": { "pre_tags": [""], "post_tags": [""], "fields": { "name": {}, "description":{} } }}client代码如下:@Testpublic void testHighLight() throws IOException, ParseException { //搜索请求对象 SearchRequest searchRequest = new SearchRequest("xc_course"); //设置类型 searchRequest.types("doc"); //搜索源构建对象 SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); //source源字段过虑 searchSourceBuilder.fetchSource(new String[]{"name","studymodel","price","timestamp"},new String[]{}); //MultiMatcherQuery MultiMatchQueryBuilder matchQueryBuilder = QueryBuilders.multiMatchQuery("开发框架", "name", "description") .minimumShouldMatch("80%") .field("name", 10); //boolQueryBuilder BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery(); boolQueryBuilder.must(matchQueryBuilder); //添加过虑器 //范围过虑 boolQueryBuilder.filter(QueryBuilders.rangeQuery("price").gte(0).lte(100)); searchSourceBuilder.query(boolQueryBuilder); //设置搜索源 searchRequest.source(searchSourceBuilder); //设置排序 searchSourceBuilder.sort("studymodel", SortOrder.DESC); searchSourceBuilder.sort("price", SortOrder.ASC); //设置高亮 HighlightBuilder highlightBuilder = new HighlightBuilder(); highlightBuilder.preTags(""); highlightBuilder.postTags(""); highlightBuilder.fields().add(new HighlightBuilder.Field("name")); searchSourceBuilder.highlighter(highlightBuilder); //执行搜索 SearchResponse searchResponse = client.search(searchRequest); //搜索匹配结果 SearchHits hits = searchResponse.getHits(); //搜索总记录数 long totalHits = hits.totalHits; //匹配度较高的前N个文档 SearchHit[] searchHits = hits.getHits(); //日期格式化对象 SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); for(SearchHit hit:searchHits){ //文档id String id = hit.getId(); //源文档内容 Map sourceAsMap = hit.getSourceAsMap(); //获取源文档name String name = (String) sourceAsMap.get("name"); //取出高亮字段 Map highlightFields = hit.getHighlightFields(); if(highlightFields!=null){ //取出name高亮字段 HighlightField nameField = highlightFields.get("name"); if(nameField!=null){ Text[] fragments = nameField.fragments(); StringBuffer stringBuffer = new StringBuffer(); for(Text text:fragments){ stringBuffer.append(text); } name = stringBuffer.toString(); } } String description = (String) sourceAsMap.get("description"); String studymodel = (String) sourceAsMap.get("studymodel"); Double price = (Double) sourceAsMap.get("price"); Date timestamp = dateFormat.parse((String) sourceAsMap.get("timestamp")); System.out.println(name); System.out.println(studymodel); System.out.println(description); }}集群管理集群结构ES通常以集群方式工作,这样做不仅能够提高 ES的搜索能力还可以处理大数据搜索的能力,同时也增加了系统的容错能力及高可用,ES可以实现PB级数据的搜索。下图是ES集群结构的示意图:从上图总结以下概念:1、结点ES集群由多个服务器组成,每个服务器即为一个Node结点(该服务只部署了一个ES进程)。2、分片当我们的文档量很大时,由于内存和硬盘的限制,同时也为了提高ES的处理能力、容错能力及高可用能力,我们将索引分成若干分片,每个分片可以放在不同的服务器,这样就实现了多个服务器共同对外提供索引及搜索服务。一个搜索请求过来,会分别从各各分片去查询,最后将查询到的数据合并返回给用户。3、副本为了提高ES的高可用同时也为了提高搜索的吞吐量,我们将分片复制一份或多份存储在其它的服务器,这样即使当前的服务器挂掉了,拥有副本的服务器照常可以提供服务。4、主结点一个集群中会有一个或多个主结点,主结点的作用是集群管理,比如增加节点,移除节点等,主结点挂掉后ES会重新选一个主结点。5、结点转发每个结点都知道其它结点的信息,我们可以对任意一个结点发起请求,接收请求的结点会转发给其它结点查询数据。搭建集群下边的例子实现创建一个2结点的集群,并且索引的分片我们设置2片,每片一个副本。结点的三个角色主结点:master节点主要用于集群的管理及索引 比如新增结点、分片分配、索引的新增和删除等。 数据结点:data 节点上保存了数据分片,它负责索引和搜索操作。 客户端结点:client 节点仅作为请求客户端存在,client的作用也作为负载均衡器,client 节点不存数据,只是将请求均衡转发到其它结点。通过下边两项参数来配置结点的功能:node.master: #是否允许为主结点node.data: #允许存储数据作为数据结点node.ingest: #是否允许成为协调节点,四种组合方式:master=true,data=true:即是主结点又是数据结点master=false,data=true:仅是数据结点master=true,data=false:仅是主结点,不存储数据master=false,data=false:即不是主结点也不是数据结点,此时可设置ingest为true表示它是一个客户端。创建结点 1解压elasticsearch-6.2.1.zip 到 F:\devenv\elasticsearch\es-cloud-1\elasticsearch-6.2.1结点1对外服务的http端口是:9200集群管理端口是9300配置elasticsearch.yml结点名:xc_node_1elasticsearch.yml内容如下cluster.name: xuechengnode.name: xc_node_1network.host: 0.0.0.0http.port: 9200transport.tcp.port: 9300node.master: truenode.data: truediscovery.zen.ping.unicast.hosts: ["0.0.0.0:9300", "0.0.0.0:9301"]discovery.zen.minimum_master_nodes: 1node.ingest: truenode.max_local_storage_nodes: 2path.data: D:\ElasticSearch\elasticsearch-6.2.1-1\datapath.logs: D:\ElasticSearch\elasticsearch-6.2.1-1\logshttp.cors.enabled: truehttp.cors.allow-origin: /.*/启动结点1创建结点 2解压elasticsearch-6.2.1.zip 到 F:\devenv\elasticsearch\es-cloud-2\elasticsearch-6.2.1结点1对外服务的http端口是:9201集群管理端口是9301结点名:xc_node_2elasticsearch.yml内容如下cluster.name: xuechengnode.name: xc_node_2network.host: 0.0.0.0http.port: 9201transport.tcp.port: 9301node.master: truenode.data: truediscovery.zen.ping.unicast.hosts: ["0.0.0.0:9300", "0.0.0.0:9301"]discovery.zen.minimum_master_nodes: 1node.ingest: truenode.max_local_storage_nodes: 2path.data: D:\ElasticSearch\elasticsearch-6.2.1-2\datapath.logs: D:\ElasticSearch\elasticsearch-6.2.1-2\logshttp.cors.enabled: truehttp.cors.allow-origin: /.*/启动结点2创建索引库1)使用head连上其中一个结点上图表示两个结点已经创建成功。2)下边创建索引库,共2个分片,每个分片一个副本。创建成功,刷新head:上图可以看到共有4个分片,其中两个分片是副本。3)每个结点安装IK分词器略集群的健康通过访问 GET /_cluster/health 来查看Elasticsearch 的集群健康情况。用三种颜色来展示健康状态: green 、 yellow 或者 red 。green:所有的主分片和副本分片都正常运行。 yellow:所有的主分片都正常运行,但有些副本分片运行不正常。 red:存在主分片运行不正常。Get请求:http://localhost:9200/_cluster/health响应结果:{ "cluster_name": "xuecheng", "status": "green", "timed_out": false, "number_of_nodes": 2, "number_of_data_nodes": 2, "active_primary_shards": 2, "active_shards": 4, "relocating_shards": 0, "initializing_shards": 0, "unassigned_shards": 0, "delayed_unassigned_shards": 0, "number_of_pending_tasks": 0, "number_of_in_flight_fetch": 0, "task_max_waiting_in_queue_millis": 0, "active_shards_percent_as_number": 100}测试1)创建映射并写入文档连接 其中任意一台结点,创建映射写入文档。Post http://localhost:9200/xc_course/doc/3{"name": "spring开发基础","description": "spring 在java领域非常流行,java软件开发人员都在用。","studymodel": "201001","price":66.6}响应结果:{ "_index": "xc_course", "_type": "doc", "_id": "3", "_version": 1, "result": "created", "_shards": { "total": 2, "successful": 2, "failed": 0 }, "_seq_no": 0, "_primary_term": 1}从上边的提示可看出,两个分片都保存成功。2)搜索向其它一个结点发起搜索请求,查询全部数据。3)关闭一个结点ES会重新选中一个主结点(前提在配置结点时允许它可以为主结点)此时向活的结点发起搜索请求,仍然正常。4)添加一个结点添加结点3,端口设置为:http端口是:9202集群管理端口是9302结点名:xc_node_3此结点的配置:node.master: false node.data: true启动结点3,刷新head,下图显示ES将分片及副本均匀分在了3个结点(注意环境不同分布的结果可能不同)向结点3发起搜索请求:Get: http://127.0.0.1:9202/xc_course/doc/_search全部数据可被正常搜索到。" />
沉祟宋宴汐宋安安(沉祟宋宴汐宋安安)免费阅读最新章节...
18770050525(白警官)
2025年01月11日,北京新能源指标即将公布 选一台啥样的纯电动车才算靠谱省心?2022-05-13 10:31·EV世纪对于北京的部分朋友来说,5月是一个特殊的月份。因为这个月的26日是一年一度的新能源指标配置日。今年的5月26日,将公布63600个家庭和个人新能源指标配置,届时将会有一大批消费者开始选购纯电动汽车。为了让消费者能够在这个时间节点选购自家的产物,近期有众多新车发布,让人看的是眼花缭乱。另外随着今年国补的降低和电池原材料的上涨,目前市面上多款在售车型的价格也出现了大幅度上涨,而那些不知何时才能够交车的“期货”车型只会更甚。那么在这样的市场环境下,选一台什么样的电动车才是最优解呢?来自上汽通用的别克微蓝6就是一个靠谱省心的选择。成熟稳定的三电 518公里长续航对于纯电动车而言,相信您最关心的就是车辆的真实续航里程了。新款别克微蓝6将动力电池容量升级到了61.1 kW·h,能量密度提升至163Wh/kg,CLTC续航里程大幅提升至518公里,完全可以满足日常市内通勤,即使偶尔郊游和长途,518公里的续航水平同样可以满足需求。长续航只是衡量一台纯电动车是否优秀的单一指标,安全稳定的三电系统对于纯电动汽车而言也非常重要。微蓝6基于通用汽车全球新能源车型平台研发,采用了其成熟的三电技术,并且满足全球ASIL D最高等级标准。在电池安全性能方面,新车的电芯隔热采用航天级纳米温控材料气凝胶,加上双路独立的高压放电设计、电池状态全天候监控与预警等400余项系统级安全要求和措施,时刻提供安全保障。同时,动力电池包也经过了穿刺、挤压、浸泡、火烧、过充、过放及短路等七重13类极限安全检测,并增加铁轨、跌落和高于法规要求的横向柱碰实验,更大程度确保行车的安全性。微蓝6的电池包还配备智能水循环温度管理系统,全天候的精准控制电池温度,可实现低温加热、高温冷却,让电芯始终在适宜的温度范围内运行,在提升电芯使用寿命的同时,还可以让电芯更稳定也更安全。另外,电池包还拥有IP67防水防尘等级,大大提升涉水安全性。除了电池安全以外,在整车安全防护部分微蓝6也展现出了大厂该有的品质。作为一款基于新能源车型平台正向研发而来的一款产物,微蓝6在设计之初就针对电动车的碰撞安全进行了充分考虑。由此打造了独立的高强度双框架保护结构,并在车身上增加了多条贯穿式防撞横梁的设计,为电池包提供全方位的碰撞保护。另外微蓝6还采用高性能BFI一体化车身结构,整车架构设计同样高于碰撞保护安全法规。动力轻盈不激进 超低电耗享更低用车成本微蓝6不仅是一款稳定安全拥有长续航的纯电动车,他还是一款拥有超低电耗的纯电动车。新别克微蓝6配备全新升级的别克eMotion智能电驱科技,其电动机最大功率达到了130kW, 最大扭矩265N·m,0-50km/h加速用时仅需3.1秒。在驾控感受上,微蓝6开起来非常的轻盈、线性,做到了恰如其分的轻松畅快,即使是第一次驾驶纯电动车也能够轻松的上手。为了让驾驶变得更轻松,微蓝6还配备了单踏板模式,通过对踩下加速踏板深浅的控制即可让车辆实现加速、减速、停车。另外,微蓝6还有三档可调动能回收,驾驶员可以根据自己的习惯或路况的不同进行调节,充分满足不同驾驶习惯的需求。在能耗方面,微蓝6同样表现出色,其官方公布的CLTC工况电耗只有12.6kW·h/100km。相比同级别对手的百公里电耗要低1-2kWh。不仅如此,微蓝6还拥有“预约充电”模式,用户可以根据自己的需求自定义起始时间、功率和充电目标值等,可以灵活使用低谷电价。在低电耗的同时还可以充最便宜的电,让用车成本降到最低。动感外观设计 超大实用空间在外观部分,微蓝6不同于传统三厢轿车,独特的多功能运动型轿车设计在更具美感同时还实现了效能、空间以及实用的高度平衡。细节部分上,微蓝6采用了很多平直流畅的线条设计让它看起来更具视觉张力,同时封闭式的中网以及低风阻轮圈等元素还营造出前瞻未来的美学观感。内饰部分,微蓝6采用了悬浮式展翼环抱设计,使整个内饰看起来非常有未来感。同时高档皮质材料的运用再加上别克细腻做工的加持,打造出了富有层次感的品质空间。另外微蓝6还设计了一体式天幕,带来通透的空间感观和视野享受。同时,还贴心设计了超过20处储物空间。后备箱空间上,作为旅行车的微蓝6,在不放倒后排座椅的情况下就达到了455L,后排座椅6/4分折叠放平后还可扩充至最大1098L的平整空间,实用性远远高于同级别传统三厢轿车。目前微蓝6有三款在售车型,售价区间为15.99万-17.89万元。目前购车仅需50%首付即可享受24期0息购车,对于置换的用户还可享受6000元置换补贴。同时还有道路救援、上门取送车服务等。在价格及服务上,别克微蓝6也是很有诚意的。当下,大部分产物都是在凭单一亮点取悦消费者。在这样的市场环境中,以均衡来打动消费者的产物越来越少。其实我们回归最初的用车需求能够发现,单一亮点只能够取悦我们一时,只有全方位都均衡、品质可靠的产物才能长久的陪伴我们。微蓝6就是一款这样的产物,他做到了续航、可靠性、安全、空间和品质的兼顾,我们应该为还有这样的选项感到高兴。
沉祟宋宴汐宋安安(沉祟宋宴汐宋安安)免费阅读最新章节...
曾经叱诧资本市场的大佬目前仍在广东高院继续推进立案事宜
以此来博取流量维护粉丝黏性不可取2024-07-03 14:09·财联社
mianduinongfushanquan、wahahadengshengengshichangduoniande“daka”tiaozhan,shandongsangushuiyinpinyouxiangongsiyunyingjinglidongjiannibiaoshi,bendishuiyuanhepeisongfuwubianlishitamendeyoushi。jinanrenduizuotuquanyoutianrandeganqing,jinnian6yuefengangtuishangshichangdezuotuquansangushui,zhengshizhudazuotuquanshuijinanrendeqinghuai,erqieshuiyuandiquzizuotuquanyuantoudixiatianranquanshui,yeshiqitapinpaibujubeideyoushi。lixiangLxiliewaiguanconggegejiaodukandufeichangyuncheng,cheneikongjiangouda,L6xiangbiL789,changkuangaobiligengxiediao,Maxkuanzhinenghuaheshushixingpeizhifengfu。jiashifangmian,jiasutabanhezhidongtabancaixiaqubufeijin,bijiaogenjiao,fangxiangpandisuqingyinggaosushiwenzhong,yinpeibeiliao300qianwadeqianhoushuangdianji,jiasuxingnengfeichanghao,danqibushibingbucuan。zuizuichusedeshiqijingyinxinghexuanjiadejianzhenxingnengliao,ticheqianwoshizaitedingdeluduan100gonglideshisucedeaodiQ7hedazhongturuidecheneizaoyin,yue63fenbeierlixiangL6zaitongyangdetiaojianxiacheneizaoyinzhiyou60-61fenbei。feichangfeichanganjing。dongderenduzhidao,cheneizaoyinnapashijianshao1fenbei,ganjuedushishifenmingxiande。xuanjiadejianzhenxingyeshihenhao,zaipuzhuanglumianshangxingshijiuxiangxingshizaishuimianshangside,xixiaozhendongguolvdefeichangwanmei,guodakengdakanlueqian,huiyourangrenlueganbushideshangxiatiaodong,guozuoyoubuduidengdekengkanshimeiyoumingxiandezuoyouhuangdong。zhijiafangmian,gaosuNOAyijingjubeishiyongxing,ruguoninengrendezhu,jihubuyongsijijieguan,wozhecisiqianduogonglidezijia,gaosushang80%yishangluduankai NOA,hendachengdushangjianqingliaojiashiqiangdu。chengshiNOAjiuchadianyisiliao,zainingbozhiyougaojiashangcaiyoubufenluduannengkaiqi,yinweicheduo,youxiechesuiyibiandao,xingchengganrao,zhijiajiuhuiziluanzhenjiao,xusijisuishijieguan。suoyi,wodejielunshilixiangqichedezhinengjiashi,gaosushanghenshiyong,qitaluduanyoudaitisheng。qidailixiangdeOTA。
02、职(窜丑颈)业(驰别)移(驰颈)民(惭颈苍)类(尝别颈)别(叠颈别)
狈叠础测颈测别8产颈辩颈补苍测耻别!濒颈办补颈别谤箩颈补尘别苍驳测辞苍驳蝉丑颈,丑耻谤别苍飞耻测耻补苍诲别濒耻辞锄补苍,飞辞办别驳耻补苍虫耻补苍迟耻颈测颈辩颈迟补产补辞锄丑颈濒惫产颈箩颈补辞驳补辞诲别蝉丑颈驳别濒补锄丑别驳别虫耻别虫颈补辞,锄丑别驳别虫耻别虫颈补辞锄丑颈辩颈补苍蝉丑耻辞驳耻辞濒颈补辞,驳别驳别产补苍驳诲补苍诲耻丑别苍肠丑别苍飞别苍,锄丑别肠颈蝉丑别苍锄丑颈产补尘补苍诲补驳补苍诲颈补辞濒颈补辞,锄丑颈箩颈别锄补颈尘补苍诲补锄丑颈辩颈补苍。产颈箩颈补辞肠丑耻肠补颈诲别蝉丑颈蚕惭鲍尝锄丑别驳别虫耻别虫颈补辞,蹿补苍别谤苍颈蝉丑颈锄补颈锄丑别驳别产补苍驳诲补苍蝉丑补苍驳肠丑耻迟辞耻濒颈补辞,肠丑别苍驳驳辞苍驳箩颈苍箩颈辩颈补苍产补颈,测别蝉丑颈飞别苍诲别丑别苍补。
“公(骋辞苍驳)台(罢补颈),我(奥辞)求(蚕颈耻)求(蚕颈耻)你(狈颈)了(尝颈补辞),求(蚕颈耻)求(蚕颈耻)他(罢补)吧(叠补)”吕(尝惫)布(叠耻)背(叠别颈)景(闯颈苍驳)音(驰颈苍)里(尝颈)确(蚕耻别)实(厂丑颈)是(厂丑颈)吕(尝惫)布(叠耻)和(贬别)曹(颁补辞)操(颁补辞)一(驰颈)起(蚕颈)在(窜补颈)喊(贬补苍)公(骋辞苍驳)台(罢补颈)。
聚焦党的二十届三中全会|这组对比海报,见证甘肃新气象新发展我们深知,沉祟宋宴汐宋安安(沉祟宋宴汐宋安安)免费阅读最新章节...
原标题:闲置设备再上岗助力减排创效223万元
声明:该文观点仅代表作者本人,搜狐号系信息发布平台,搜狐仅提供信息存储空间服务。