-
目前官网最新Elasticsearch版本为 8.13.x ,而目前华为镜像站最新版为 7.10.2请问一下华为云后面有更新8.x的计划?有的话,大概什么时候?
-
目前华为云上的css中的Elasticsearch7.10.2版本的实例,是否支持jdbc方式访问?好像没有看到这方面的信息
-
异常代码配置文件yarn报错
-
[问题求助] python 库elasticsearch 7.13.4,连接elasticsearch 7.93服务器,如何通过Urllib3HttpConnection方式,进行kerberos认证from requests_gssapi import HTTPKerberosAuthreturn Elasticsearch([{'host': config.IP, 'port': config.Port}], verify_certs=False, connection_class=RequestsHttpConnection http_auth=HTTPKerberosAuth(), timeout=20, scheme='https')老方式是使用的RequestsHttpConnection连接,但是连接elasticsearch7.93,出现间歇性中断,要修改为使用Urllib3HttpConnection应该如何处理
-
之前在Python中通过用户名和密码连接并使用ES,可以成功( ES版本为7.10 ):import requestsfrom requests.auth import HTTPBasicAuthresp = requests.get(url='xxx', data=xxx, headers=xxx, auth=HTTPBasicAuth(es_user, es_pwd), verify=False)目前因为某些原因,需要改为kerberos认证方式,但报错:Max retries exceeded with url: xxx (caused by SSLError(SSLError("bad handshake: Error([('SSL routines', 'ssl3_get_server_certificate', 'certificate verify failed')],)",),))代码如下:( requests_kerberos版本为0.10.0 )import osimport requestsfrom requests_kerberos import HTTPKerberosAuthos.environ['KRB5_CONFIG'] = 'xxx/krb5.conf'os.environ['KRB5_KTNAME'] = 'xxx/user.keytab'resp = requests.get(url='xxx', data=xxx, headers=xxx, auth=HTTPKerberosAuth(principal='xxx', mutual_authentication=DISABLED), verify=False)2种方式只是 requests auth 参数不同,请老师们帮忙看看是哪里的问题 ?
-
之前在Python中通过以下方式连接并使用ES( ES版本为7.10 ):import requestsfrom requests.auth import HTTPBasicAuthresp = requests.get(url='xxx', data=xxx, headers=xxx, auth=HTTPBasicAuth(es_user, es_pwd), verify=False)目前因为某些原因,需要改为kerberos认证方式,但报错:Max retries exceeded with url: xxx (caused by SSLError(SSLError("bad handshake: Error([('SSL routines', 'ssl3_get_server_certificate', 'certificate verify failed')],)",),))代码如下:import osimport requestsfrom requests_kerberos import HTTPKerberosAuthos.environ['KRB5_CONFIG'] = 'xxx/krb5.conf'os.environ['KRB5_KTNAME'] = 'xxx/user.keytab'resp = requests.get(url='xxx', data=xxx, headers=xxx, auth=HTTPKerberosAuth(principal='xxx'))
-
求助!重启了logstash,就一直报这个错,多次重启都没用[2024-03-05T18:09:29,606][WARN ][logstash.outputs.elasticsearch][main] Attempted to resurrect connection to dead ES instance, but got an error. {:url=>"https://ty:xxxxxx@10.x.x.xx:24100/", :error_type=>LogStash::Outputs::ElasticSearch::HttpClient::Pool::HostUnreachableError, :error=>"Elasticsearch Unreachable: [https://ty_ywzx:xxxxxx@10.xxx.x.xxx:24100/][Manticore::ClientProtocolException] PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target"}
-
Java中使用Elasticsearch服务的示例代码如下:首先,确保你已经安装了Elasticsearch,并且它正在运行。接下来,你需要添加Elasticsearch的Java客户端库到你的项目中。你可以使用Maven或Gradle来管理依赖项。Maven依赖项:<dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>elasticsearch-rest-high-level-client</artifactId> <version>7.10.2</version> </dependency>Gradle依赖项:implementation 'org.elasticsearch.client:elasticsearch-rest-high-level-client:7.10.2'接下来,你可以使用以下示例代码来连接到Elasticsearch并执行一些基本的操作:import org.elasticsearch.action.get.GetRequest; import org.elasticsearch.action.get.GetResponse; import org.elasticsearch.client.RequestOptions; import org.elasticsearch.client.RestHighLevelClient; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.search.builder.SearchSourceBuilder; import java.io.IOException; public class ElasticsearchExample { public static void main(String[] args) { // 创建Elasticsearch客户端 RestHighLevelClient client = new RestHighLevelClient( RestClient.builder(new HttpHost("localhost", 9200, "http"))); try { // 构建查询请求 SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); searchSourceBuilder.query(QueryBuilders.matchAllQuery()); searchSourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS)); // 执行查询请求 GetRequest getRequest = new GetRequest("your_index_name", "your_document_id"); getRequest.source(searchSourceBuilder); GetResponse getResponse = client.get(getRequest, RequestOptions.DEFAULT); // 处理查询结果 if (getResponse.isExists()) { System.out.println("找到了匹配的文档!"); String sourceAsString = getResponse.getSourceAsString(); System.out.println(sourceAsString); } else { System.out.println("未找到匹配的文档。"); } } catch (IOException e) { e.printStackTrace(); } finally { // 关闭Elasticsearch客户端 try { client.close(); } catch (IOException e) { e.printStackTrace(); } } } }在上面的示例代码中,我们首先创建了一个RestHighLevelClient对象来连接到Elasticsearch。然后,我们构建了一个查询请求,使用matchAllQuery()方法来匹配所有文档。接下来,我们执行查询请求并处理查询结果。最后,我们关闭了Elasticsearch客户端。请注意,你需要将your_index_name替换为你要查询的实际索引名称,将your_document_id替换为你要查询的实际文档ID。这只是一个简单的示例,你可以根据自己的需求进行更复杂的操作,例如搜索特定条件的文档、更新文档、删除文档等。
-
搜索引擎是现代化的网络技术之一。搜索引擎的主要工作是在用户查询时返回包含相关信息的文档列表,它可以用于Web搜索,企业搜索和数据搜索等多个领域。Solr和Elasticsearch(ES)是两个受欢迎的开源搜索引擎,它们都基于Lucene,都提供了全文搜索、分布式架构和强大的API等特征。下面我们将对Solr和Elasticsearch进行详细的介绍。一、SolrSolr是一个开源的搜索平台,适用于 Web 搜索、企业搜索以及数据搜索等领域。它提供了全文搜索、分布式架构和强大的HTTP API等特点。Solr最初是由Apache Software Foundation开发并支持的,它是基于Lucene Java库构建而成的。Solr提供了一组充分证明了性能和可扩展性的核心功能,包括数据分片、复制、高可用性、集群管理、查询和索引优化。Solr的优点如下:大规模数据处理与搜索:Solr强大的文本分析器和查询模式的灵活性,使得 Solr 能够进行大量数据的处理与搜索。相对简单的安装:Solr的安装非常简单,它支持多种操作系统,提供了多种方式进行部署。多语言支持:Solr支持多语言搜索,它能够处理包括泰语、中文、日语、朝鲜语等在内的多种语言。二、Elasticsearch(ES)ES是一个基于开源搜索引擎Lucene的分布式、RESTful的搜索系统。它不但具有强大的搜索能力,还具有快速稳定的响应性和可扩展性。ES不仅支持全文搜索,还支持结构化数据搜索、地理数据搜索、大数据分析和监控等场景。ES创建的目的是提供一个容易扩展和管理的搜索引擎,它提供了许多强大和易用的功能,如近实时搜索、动态字段支持、自动索引、多租户和强大的文本搜索等。ES的优点如下:高性能:ES内部采用了许多优化技术,支持近实时搜索、分布式搜索和索引等优点,可处理大量数据的搜索请求。功能完善:ES支持多种数据类型,数据可导入到ES中,支持结构化和半结构化数据,并且拥有强大的聚合分析功能。可扩展性:ES基于分布式架构,每个节点都可以承载数据、进行存储和计算处理,可实现水平扩展。Solr和Elasticsearch的区别主要在于:架构设计:Solr采用独立的Solr服务器和Solr客户端,而ES基于分布式架构,节点可以担任多个角色。文档存储:Solr文档必须在对应的Shard中存储,而ES不同,ES文档可以存储到初始节点或分片节点中。数据同步:Solr通过复制索引的方式进行数据同步,ES通过传输可序列化的JSON数据进行同步。综上所述,Solr和Elasticsearch虽然都基于Lucene,但是它们的架构设计、文档存储和数据同步方式还是有所不同,所以在选择时需要根据实际情况进行权衡和选择
-
1 text_en_splitting_tight分词名称分词器和过滤器输入分词效果text_en_splitting_tight1.中英文根据空格分词2.替换成同义词,比如搜索北大换成北京大学3.删除停顿词,比如a an but4.把特殊符号去掉,比如wi-fi 替换成wifi5.大写转换成小写6.保护词免于被分词器修改7.英文单词复数变单数形势(比如dogs变成dog)8.避免重复处理我们 的祖国 名称 是 ChI_na, we are 北大 dogs我们的祖国名称是chinawe北京大学dog1.1 创建分词器curl -XPUT --tlsv1.2 --negotiate -k -u : "https://xx.xx:24100/h0323?pretty" -H 'Content-Type:application/json' -d'{"settings": {"analysis": {"char_filter": {"my_char_filter": {"type": "mapping","mappings": ["北大 =>北京大学","_ => "]}},"filter": {"my_stopword": {"type": "stop","stopwords": ["a","an", "but","are"]}},"tokenizer":{"my_tokenizer":{"type":"pattern","pattern":"[ ]"}},"analyzer":{"text_en_splitting_tight":{"type":"custom","char_filter":["my_char_filter"],"filter":["my_stopword","lowercase"],"tokenizer":"my_tokenizer"}}}}}'1.2 输入查询curl -XGET --tlsv1.2 --negotiate -k -u : "https://xx.xx:24100/h0323/_analyze?pretty" -H 'Content-Type:application/json' -d'{ "analyzer":"text_en_splitting_tight","text":"我们 的祖国 名称 是 ChI_na, we are 北大 dogs"}'2 text_general分词名称分词器和过滤器输入分词效果text_generalIndex1.自动给拆分成的单个词添加type2.删除停顿词,比如a an but3.大写转换成小写我们 的祖国 名称 是 ChI_na, we are 北大 dogs我们的祖国名称是chinawe北大dogsquery1.自动给拆分成的单个词添加type2.删除停顿词,比如a an but3.替换成同义词,比如搜索北大换成北京大学4.大写转换成小写我们 的祖国 名称 是 ChI_na, we are 北大 dogs我们的祖国名称是chinawe北京大学dogs2.1 分词创建-indexcurl -XPUT --tlsv1.2 --negotiate -k -u : "https://xx.xx:24100/h0323?pretty" -H 'Content-Type:application/json' -d'{"settings": {"analysis": {"char_filter": {"my_char_filter": {"type": "mapping","mappings": ["_ => "]}},"filter": {"my_stopword": {"type": "stop","stopwords": ["a","an", "but","are"]}},"tokenizer":{"my_tokenizer":{"type":"pattern","pattern":"[ ]"}},"analyzer":{"text_general":{"type":"custom","char_filter":["my_char_filter"],"filter":["my_stopword","lowercase"],"tokenizer":"my_tokenizer"}}}}}'2.2 输入查询-indexcurl -XGET --tlsv1.2 --negotiate -k -u : "https://xx.xx:24100/h0323/_analyze?pretty" -H 'Content-Type:application/json' -d'{ "analyzer":"text_general","text":"我们 的祖国 名称 是 ChI_na, we are 北大 dogs"}'2.3 分词创建-querycurl -XPUT --tlsv1.2 --negotiate -k -u : "https://xx.xx:24100/h0323?pretty" -H 'Content-Type:application/json' -d'{"settings": {"analysis": {"char_filter": {"my_char_filter": {"type": "mapping","mappings": ["北大 =>北京大学","_ => "]}},"filter": {"my_stopword": {"type": "stop","stopwords": ["a","an", "but","are"]}},"tokenizer":{"my_tokenizer":{"type":"pattern","pattern":"[ ]"}},"analyzer":{"text_general":{"type":"custom","char_filter":["my_char_filter"],"filter":["my_stopword","lowercase"],"tokenizer":"my_tokenizer"}}}}}'2.4 输入查询-querycurl -XGET --tlsv1.2 --negotiate -k -u : "https://xx.xx:24100/h0323/_analyze?pretty" -H 'Content-Type:application/json' -d'{ "analyzer":"text_general","text":"我们 的祖国 名称 是 ChI_na, we are 北大 dogs"}'
-
Lucene(或Elasticsearch)使用布尔模型(Boolean model) 查找匹配文档,并用一个名为实用评分函数(practical scoring function) 的公式来计算相关度。ES中的自定义评分机制function_score主要用于让用户自定义查询相关性得分,实现精细化控制评分的目的详细参考: https://www.elastic.co/guide/cn/elasticsearch/guide/current/practical-scoring-function.html1 创建索引curl -XPUT cid:link_02 创建mappingcurl -H "Content-Type: application/json" -XPUT cid:link_0/video/_mapping?include_type_name=true -d '{ "video": { "properties": { "title": { "type": "text", "analyzer": "snowball" }, "description": { "type": "text", "analyzer": "snowball" }, "views": { "type": "integer" }, "likes": { "type": "integer" }, "created_at": { "type": "date" } } }}'3 添加数据curl -H "Content-Type: application/json" -XPUT cid:link_0/video/1 -d '{ "title": "Sick Sad World: Cold Breeze on the Interstate", "description": "Is your toll collector wearing pants a skirt or nothing but a smile Cold Breeze on the Interstate next on Sick ", "views": 500, "likes":2, "created_at": "2023-04-22T08:00:00"}'curl -H "Content-Type: application/json" -XPUT cid:link_0/video/2 -d '{ "title": "Sick Sad World: The Severed Pianist", "description": "When he turned up his nose at accordion lessons, they cut off his inheritance molto allegro. The Severed Pianist, ne", "views": 6000, "likes": 100, "created_at": "2023-04-22T12:00:00"}'curl -H "Content-Type: application/json" -XPUT cid:link_0/video/3 -d '{ "title": "Sick Sad World: Avant Garde Obstetrician", "description": "Meet the avant-garde obstetrician who has turned his cast offs into art work. Severed Umbilical cord sculpture next,", "views": 100, "likes": 130, "created_at": "2023-04-22T23:00:00"}'4 计算分数错误样例:curl -H "Content-Type: application/json" -XPOST cid:link_0/video/_search -d '{ "query": { "function_score": { "query": { "match": { "_all": "severed" } }, "script_score": { "script": "_score * Math.log(doc['likes'].value + doc['views'].value + 1)" } } }}'正确样例,注意单引号 \u0027A、使用ES内置的script_score方法计算分数curl -X GET "cid:link_0/video/_search?pretty" -H 'Content-Type: application/json' –d '{ "query": { "function_score": { "query": { "match": { "_all": "severed" } }, "script_score": { "script": { "source": "Math.log(2 + doc[\u0027likes\u0027].value)" } } } }}'输出结果:{ "took" : 3, "timed_out" : false, "_shards" : { "total" : 1, "successful" : 1, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : { "value" : 0, "relation" : "eq" }, "max_score" : null, "hits" : [ ] }}B、使用衰减函数linear计算分数curl -H "Content-Type: application/json" -XPOST cid:link_0/video/_search -d ' { "query": { "function_score": { "functions": [ { "linear": { "views": { "origin": 5000, "scale": 2500 } } }, { "linear": { "likes": { "origin": 200, "scale": 90 } } } ] } }}'输出结果:{ "took": 5, "timed_out": false, "_shards": { "total": 1, "successful": 1, "skipped": 0, "failed": 0 }, "hits": { "total": { "value": 3, "relation": "eq" }, "max_score": 0.35555556, "hits": [ { "_index": "searchtub_2", "_type": "video", "_id": "2", "_score": 0.35555556, "_source": { "title": "Sick Sad World: The Severed Pianist", "description": "When he turned up his nose at accordion lessons, they cut off his inheritance molto allegro. The Severed Pianist, ne", "views": 6000, "likes": 100, "created_at": "2023-04-22T12:00:00" } }, { "_index": "searchtub_2", "_type": "video", "_id": "3", "_score": 0.012222222, "_source": { "title": "Sick Sad World: Avant Garde Obstetrician", "description": "Meet the avant-garde obstetrician who has turned his cast offs into art work. Severed Umbilical cord sculpture next,", "views": 100, "likes": 130, "created_at": "2023-04-22T23:00:00" } }, { "_index": "searchtub_2", "_type": "video", "_id": "1", "_score": 0, "_source": { "title": "Sick Sad World: Cold Breeze on the Interstate", "description": "Is your toll collector wearing pants a skirt or nothing but a smile Cold Breeze on the Interstate next on Sick ", "views": 500, "likes": 2, "created_at": "2023-04-22T08:00:00" } } ] }}
-
一、简介在之前的文章中, 我们详细的介绍了 ElasticSearch 的安装与使用,详细大家对 ElasticSearch 有了初步的认识。本文将重点介绍 SpringBoot 整合 ElasticSearch 做搜索引擎,实现亿量级数据的快速查询。废话不多说,直接上代码!二、代码实践本文采用的SpringBoot版本号是2.1.0.RELEASE,服务端 es 的版本号是6.8.2,客户端采用的是官方推荐的Elastic Java High Level Rest Client版本号是6.8.2,方便与SpringBoot的版本兼容。es 最大的亮点就是查询非常丰富,可以在上亿的数据里面快速搜索出目标数据,查询如果实现呢?请看下文单条件精确查询 codeduidaima.com@RunWith(SpringJUnit4ClassRunner.class)@SpringBootTest(classes = ElasticSearchApplication.class)public class SearchJunit {@Autowiredprivate RestHighLevelClient client;/*** 堆代码 duidaima.com* 单条件精确查询* @throws IOException*/@Testpublic void search0() throws IOException {// 创建请求SearchSourceBuilder builder = new SearchSourceBuilder().query(QueryBuilders.termsQuery("name", "赵里"));//搜索SearchRequest searchRequest = new SearchRequest();searchRequest.indices("cs_index");searchRequest.types("_doc");searchRequest.source(builder);// 执行请求SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);// 解析查询结果System.out.println(response.toString());}}多条件精确查询,取并集 codeduidaima.com@RunWith(SpringJUnit4ClassRunner.class)@SpringBootTest(classes = ElasticSearchApplication.class)public class SearchJunit {@Autowiredprivate RestHighLevelClient client;/*** 多条件精确查询,取并集* @throws IOException*/@Testpublic void search1() throws IOException {// 创建请求SearchSourceBuilder builder = new SearchSourceBuilder().query(QueryBuilders.termsQuery("name", "张", "陈"));//搜索SearchRequest searchRequest = new SearchRequest();searchRequest.indices("cs_index");searchRequest.types("_doc");searchRequest.source(builder);// 执行请求SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);// 解析查询结果System.out.println(response.toString());}}范围查询 codeduidaima.com@RunWith(SpringJUnit4ClassRunner.class)@SpringBootTest(classes = ElasticSearchApplication.class)public class SearchJunit {@Autowiredprivate RestHighLevelClient client;/*** 范围查询,包括from、to* @throws IOException*/@Testpublic void search2() throws IOException {// 创建请求SearchSourceBuilder builder = new SearchSourceBuilder().query(QueryBuilders.rangeQuery("age").from(20).to(32));//搜索SearchRequest searchRequest = new SearchRequest();searchRequest.indices("cs_index");searchRequest.types("_doc");searchRequest.source(builder);// 执行请求SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);// 解析查询结果System.out.println(response.toString());}/*** 范围查询,不包括from、to* @throws IOException*/@Testpublic void search3() throws IOException {// 创建请求SearchSourceBuilder builder = new SearchSourceBuilder().query(QueryBuilders.rangeQuery("age").from(20,false).to(30, false));//搜索SearchRequest searchRequest = new SearchRequest();searchRequest.indices("cs_index");searchRequest.types("_doc");searchRequest.source(builder);// 执行请求SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);// 解析查询结果System.out.println(response.toString());}/*** 范围查询, lt:小于,gt:大于* @throws IOException*/@Testpublic void search4() throws IOException {// 创建请求SearchSourceBuilder builder = new SearchSourceBuilder().query(QueryBuilders.rangeQuery("age").lt(30).gt(20));//搜索SearchRequest searchRequest = new SearchRequest();searchRequest.indices("cs_index");searchRequest.types("_doc");searchRequest.source(builder);// 执行请求SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);// 解析查询结果System.out.println(response.toString());}}模糊查询,支持通配符 codeduidaima.com@RunWith(SpringJUnit4ClassRunner.class)@SpringBootTest(classes = ElasticSearchApplication.class)public class SearchJunit {@Autowiredprivate RestHighLevelClient client;/*** 模糊查询,支持通配符* @throws IOException*/@Testpublic void search5() throws IOException {// 创建请求SearchSourceBuilder builder = new SearchSourceBuilder().query(QueryBuilders.wildcardQuery("name","张三"));//搜索SearchRequest searchRequest = new SearchRequest();searchRequest.indices("cs_index");searchRequest.types("_doc");searchRequest.source(builder);// 执行请求SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);// 解析查询结果System.out.println(response.toString());}}不使用通配符的模糊查询,左右匹配 codeduidaima.com@RunWith(SpringJUnit4ClassRunner.class)@SpringBootTest(classes = ElasticSearchApplication.class)public class SearchJunit {@Autowiredprivate RestHighLevelClient client;/*** 不使用通配符的模糊查询,左右匹配* @throws IOException*/@Testpublic void search6() throws IOException {// 创建请求SearchSourceBuilder builder = new SearchSourceBuilder().query(QueryBuilders.queryStringQuery("张三").field("name"));//搜索SearchRequest searchRequest = new SearchRequest();searchRequest.indices("cs_index");searchRequest.types("_doc");searchRequest.source(builder);// 执行请求SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);// 解析查询结果System.out.println(response.toString());}}多字段模糊查询 codeduidaima.com@RunWith(SpringJUnit4ClassRunner.class)@SpringBootTest(classes = ElasticSearchApplication.class)public class SearchJunit {@Autowiredprivate RestHighLevelClient client;/*** 多字段模糊查询* @throws IOException*/@Testpublic void search7() throws IOException {// 创建请求SearchSourceBuilder builder = new SearchSourceBuilder().query(QueryBuilders.multiMatchQuery("长", "name", "city"));//搜索SearchRequest searchRequest = new SearchRequest();searchRequest.indices("cs_index");searchRequest.types("_doc");searchRequest.source(builder);// 执行请求SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);// 解析查询结果System.out.println(response.toString());}}多字段模糊查询 codeduidaima.com@RunWith(SpringJUnit4ClassRunner.class)@SpringBootTest(classes = ElasticSearchApplication.class)public class SearchJunit {@Autowiredprivate RestHighLevelClient client;/*** 堆代码 duidaima.com* 分页搜索* @throws IOException*/@Testpublic void search8() throws IOException {// 创建请求SearchSourceBuilder builder = new SearchSourceBuilder().from(0).size(2);//搜索SearchRequest searchRequest = new SearchRequest();searchRequest.indices("cs_index");searchRequest.types("_doc");searchRequest.source(builder);// 执行请求SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);// 解析查询结果System.out.println(response.toString());}}字段排序 codeduidaima.com@RunWith(SpringJUnit4ClassRunner.class)@SpringBootTest(classes = ElasticSearchApplication.class)public class SearchJunit {@Autowiredprivate RestHighLevelClient client;/*** 排序,字段的类型必须是:integer、double、long或者keyword* @throws IOException*/@Testpublic void search9() throws IOException {// 创建请求SearchSourceBuilder builder = new SearchSourceBuilder().sort("createTime", SortOrder.ASC);//搜索SearchRequest searchRequest = new SearchRequest();searchRequest.indices("cs_index");searchRequest.types("_doc");searchRequest.source(builder);// 执行请求SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);// 解析查询结果System.out.println(response.toString());}}精确统计筛选文档数 codeduidaima.com@RunWith(SpringJUnit4ClassRunner.class)@SpringBootTest(classes = ElasticSearchApplication.class)public class SearchJunit {@Autowiredprivate RestHighLevelClient client;/*** 精确统计筛选文档数,查询性能有所降低* @throws IOException*/@Testpublic void search10() throws IOException {// 创建请求SearchSourceBuilder builder = new SearchSourceBuilder().trackTotalHits(true);//搜索SearchRequest searchRequest = new SearchRequest();searchRequest.indices("cs_index");searchRequest.types("_doc");searchRequest.source(builder);// 执行请求SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);// 解析查询结果System.out.println(response.toString());}}设置源字段过滤返回 codeduidaima.com@RunWith(SpringJUnit4ClassRunner.class)@SpringBootTest(classes = ElasticSearchApplication.class)public class SearchJunit {@Autowiredprivate RestHighLevelClient client;/*** 设置源字段过虑,第一个参数结果集包括哪些字段,第二个参数表示结果集不包括哪些字段* @throws IOException*/@Testpublic void search11() throws IOException {// 创建请求SearchSourceBuilder builder = new SearchSourceBuilder().fetchSource(new String[]{"name","age","city","createTime"},new String[]{});//搜索SearchRequest searchRequest = new SearchRequest();searchRequest.indices("cs_index");searchRequest.types("_doc");searchRequest.source(builder);// 执行请求SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);// 解析查询结果System.out.println(response.toString());}}根据 id 精确匹配 codeduidaima.com@RunWith(SpringJUnit4ClassRunner.class)@SpringBootTest(classes = ElasticSearchApplication.class)public class SearchJunit {@Autowiredprivate RestHighLevelClient client;/*** 根据id精确匹配* @throws IOException*/@Testpublic void search12() throws IOException {String[] ids = new String[]{"1","2"};// 创建请求SearchSourceBuilder builder = new SearchSourceBuilder().query(QueryBuilders.termsQuery("_id", ids));//搜索SearchRequest searchRequest = new SearchRequest();searchRequest.indices("cs_index");searchRequest.types("_doc");searchRequest.source(builder);// 执行请求SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);// 解析查询结果System.out.println(response.toString());}}matchAllQuery 搜索全部 codeduidaima.com@RunWith(SpringJUnit4ClassRunner.class)@SpringBootTest(classes = ElasticSearchApplication.class)public class SearchJunit {@Autowiredprivate RestHighLevelClient client;/*** matchAllQuery搜索全部* @throws IOException*/@Testpublic void search21() throws IOException {// 创建请求SearchSourceBuilder builder = new SearchSourceBuilder().query(QueryBuilders.matchAllQuery());//搜索SearchRequest searchRequest = new SearchRequest();searchRequest.indices("cs_index");searchRequest.types("_doc");searchRequest.source(builder);// 执行请求SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);// 解析查询结果System.out.println(response.toString());}}match 搜索匹配 codeduidaima.com@RunWith(SpringJUnit4ClassRunner.class)@SpringBootTest(classes = ElasticSearchApplication.class)public class SearchJunit {@Autowiredprivate RestHighLevelClient client;/*** match搜索匹配* @throws IOException*/@Testpublic void search22() throws IOException {// 创建请求SearchSourceBuilder builder = new SearchSourceBuilder().query(QueryBuilders.matchQuery("name", "张王"));//搜索SearchRequest searchRequest = new SearchRequest();searchRequest.indices("cs_index");searchRequest.types("_doc");searchRequest.source(builder);// 执行请求SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);// 解析查询结果System.out.println(response.toString());}}bool组合查询 codeduidaima.com@RunWith(SpringJUnit4ClassRunner.class)@SpringBootTest(classes = ElasticSearchApplication.class)public class SearchJunit {@Autowiredprivate RestHighLevelClient client;/*** bool组合查询* @throws IOException*/@Testpublic void search23() throws IOException {// 创建请求SearchSourceBuilder builder = new SearchSourceBuilder();BoolQueryBuilder boolQueryBuilder=new BoolQueryBuilder();boolQueryBuilder.must(QueryBuilders.matchQuery("name", "张王"));boolQueryBuilder.must(QueryBuilders.rangeQuery("age").lte(30).gte(20));builder.query(boolQueryBuilder);//搜索SearchRequest searchRequest = new SearchRequest();searchRequest.indices("cs_index");searchRequest.types("_doc");searchRequest.source(builder);// 执行请求SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);// 解析查询结果System.out.println(response.toString());}}nested 类型嵌套查询 codeduidaima.com@RunWith(SpringJUnit4ClassRunner.class)@SpringBootTest(classes = ElasticSearchApplication.class)public class SearchJunit {@Autowiredprivate RestHighLevelClient client;/*** nested类型嵌套查询* @throws IOException*/@Testpublic void search24() throws IOException {// 创建请求SearchSourceBuilder builder = new SearchSourceBuilder();//条件查询BoolQueryBuilder mainBool=new BoolQueryBuilder();mainBool.must(QueryBuilders.matchQuery("name", "赵六"));//nested类型嵌套查询BoolQueryBuilder boolQueryBuilder=new BoolQueryBuilder();boolQueryBuilder.must(QueryBuilders.matchQuery("products.brand", "A"));boolQueryBuilder.must(QueryBuilders.matchQuery("products.title", "巧克力"));NestedQueryBuilder nested = QueryBuilders.nestedQuery("products",boolQueryBuilder, ScoreMode.None);mainBool.must(nested);builder.query(mainBool);//搜索SearchRequest searchRequest = new SearchRequest();searchRequest.indices("cs_index");searchRequest.types("_doc");searchRequest.source(builder);// 执行请求SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);// 解析查询结果System.out.println(response.toString());}}多条件查询 + 排序 + 分页 codeduidaima.com@RunWith(SpringJUnit4ClassRunner.class)@SpringBootTest(classes = ElasticSearchApplication.class)public class SearchJunit {@Autowiredprivate RestHighLevelClient client;/*** 多条件查询 + 排序 + 分页* @throws IOException*/@Testpublic void search29() throws IOException {// 创建请求SearchSourceBuilder builder = new SearchSourceBuilder();//条件搜索BoolQueryBuilder boolQueryBuilder=new BoolQueryBuilder();boolQueryBuilder.must(QueryBuilders.matchQuery("name", "张王"));boolQueryBuilder.must(QueryBuilders.rangeQuery("age").lte(30).gte(20));builder.query(boolQueryBuilder);//结果集合分页builder.from(0).size(2);//排序builder.sort("createTime",SortOrder.ASC);//搜索SearchRequest searchRequest = new SearchRequest();searchRequest.indices("cs_index");searchRequest.types("_doc");searchRequest.source(builder);// 执行请求SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);// 解析查询结果System.out.println(response.toString());}}聚合查询-求和 codeduidaima.com@RunWith(SpringJUnit4ClassRunner.class)@SpringBootTest(classes = ElasticSearchApplication.class)public class SearchJunit {@Autowiredprivate RestHighLevelClient client;/*** 聚合查询 sum* @throws IOException*/@Testpublic void search30() throws IOException {// 创建请求SearchSourceBuilder builder = new SearchSourceBuilder();//条件搜索builder.query(QueryBuilders.matchAllQuery());//聚合查询AggregationBuilder aggregation = AggregationBuilders.sum("sum_age").field("age");builder.aggregation(aggregation);//搜索SearchRequest searchRequest = new SearchRequest();searchRequest.indices("cs_index");searchRequest.types("_doc");searchRequest.source(builder);// 执行请求SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);// 解析查询结果System.out.println(response.toString());}}聚合查询-求平均值 codeduidaima.com@RunWith(SpringJUnit4ClassRunner.class)@SpringBootTest(classes = ElasticSearchApplication.class)public class SearchJunit {@Autowiredprivate RestHighLevelClient client;/*** 聚合查询 avg* @throws IOException*/@Testpublic void search31() throws IOException {// 创建请求SearchSourceBuilder builder = new SearchSourceBuilder();//条件搜索builder.query(QueryBuilders.matchAllQuery());//聚合查询AggregationBuilder aggregation = AggregationBuilders.avg("avg_age").field("age");builder.aggregation(aggregation);//搜索SearchRequest searchRequest = new SearchRequest();searchRequest.indices("cs_index");searchRequest.types("_doc");searchRequest.source(builder);// 执行请求SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);// 解析查询结果System.out.println(response.toString());}}聚合查询-计数 codeduidaima.com@RunWith(SpringJUnit4ClassRunner.class)@SpringBootTest(classes = ElasticSearchApplication.class)public class SearchJunit {@Autowiredprivate RestHighLevelClient client;/*** 聚合查询 count* @throws IOException*/@Testpublic void search32() throws IOException {// 创建请求SearchSourceBuilder builder = new SearchSourceBuilder();//条件搜索builder.query(QueryBuilders.matchAllQuery());//聚合查询AggregationBuilder aggregation = AggregationBuilders.count("count_age").field("age");builder.aggregation(aggregation);//搜索SearchRequest searchRequest = new SearchRequest();searchRequest.indices("cs_index");searchRequest.types("_doc");searchRequest.source(builder);// 执行请求SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);// 解析查询结果System.out.println(response.toString());}}聚合查询-分组 codeduidaima.com@RunWith(SpringJUnit4ClassRunner.class)@SpringBootTest(classes = ElasticSearchApplication.class)public class SearchJunit {@Autowiredprivate RestHighLevelClient client;/*** 聚合查询 分组* @throws IOException*/@Testpublic void search33() throws IOException {// 创建请求SearchSourceBuilder builder = new SearchSourceBuilder();//条件搜索builder.query(QueryBuilders.matchAllQuery());//聚合查询AggregationBuilder aggregation = AggregationBuilders.terms("tag_createTime").field("createTime").subAggregation(AggregationBuilders.count("count_age").field("age")) //计数.subAggregation(AggregationBuilders.sum("sum_age").field("age")) //求和.subAggregation(AggregationBuilders.avg("avg_age").field("age")); //求平均值builder.aggregation(aggregation);//不输出原始数据builder.size(0);//搜索SearchRequest searchRequest = new SearchRequest();searchRequest.indices("cs_index");searchRequest.types("_doc");searchRequest.source(builder);// 执行请求SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);// 解析查询结果System.out.println(response.toString());}}三、小结本文主要围绕 SpringBoot 整合 ElasticSearch 进行各种高级查询的介绍,希望对大家有所帮助!转载自cid:link_0Group/Topic/JAVA/10446
-
版本关系依赖<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch</artifactId> </dependency>配置server: port: 8082 spring: elasticsearch: rest: uris: 192.168.25.131:9200实体类@Data @AllArgsConstructor @NoArgsConstructor //indexName名字如果是字母那么必须是小写字母 @Document(indexName = "student") public class Student { @Id @Field(store = true, type = FieldType.Keyword) private String sId; @Field(store = true, type = FieldType.Keyword) private String sName; @Field(store = true, type = FieldType.Text, analyzer = "ik_smart") //Text可以分词 ik_smart=粗粒度分词 ik_max_word 为细粒度分词 private String sAddress; @Field(index = false, store = true, type = FieldType.Integer) private Integer sAge; @Field(index = false, store = true, type = FieldType.Date, format = DateFormat.basic_date_time) private Date sCreateTime; @Field(type = FieldType.Keyword) private String[] sCourseList; //数组类型 由数组中第一个非空值决定(这里数组和集合一个意思了) @Field(type = FieldType.Keyword) private List<String> sColorList; //集合类型 由数组中第一个非空值决定 }ElasticsearchRepository接口/** * @author: zhouwenjie * @description: * @create: 2022-05-12 17:37 * ElasticsearchRepository<T, ID> T:实体类泛型,ID:实体类主键类型 **/ public interface StudentMapper extends ElasticsearchRepository<Student, String> { }调用@Test void contextLoads2() { List<String> colorList = new ArrayList<>();//颜色 colorList.add("red"); colorList.add("white"); colorList.add("black"); Student student = new Student("1", "mhh", "济南", 12, new Date(), new String[]{"语文", "数学", "英语"}, colorList); Student save = restTemplate.save(student); System.out.println(save); }
-
1.创建工程,引入依赖<dependencies> <dependency> <groupId>org.elasticsearch</groupId> <artifactId>elasticsearch</artifactId> <version>5.6.8</version> </dependency> <dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>transport</artifactId> <version>5.6.8</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-to-slf4j</artifactId> <version>2.9.1</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.24</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-simple</artifactId> <version>1.7.21</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.12</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> </dependencies>2.创建索引index@Test //创建索引 public void test1() throws Exception{ // 创建Client连接对象 Settings settings = Settings.builder().put("cluster.name", "my-elasticsearch").build(); TransportClient client = new PreBuiltTransportClient(settings) .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300)); //创建名称为blog2的索引 client.admin().indices().prepareCreate("blog2").get(); //释放资源 client.close(); }3.创建映射mapping@Test //创建映射 public void test3() throws Exception{ // 创建Client连接对象 Settings settings = Settings.builder().put("cluster.name", "my-elasticsearch").build(); TransportClient client = new PreBuiltTransportClient(settings) .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300)); // 添加映射 /** * 格式: * "mappings" : { "article" : { "dynamic" : "false", "properties" : { "id" : { "type" : "string" }, "content" : { "type" : "string" }, "author" : { "type" : "string" } } } } */ XContentBuilder builder = XContentFactory.jsonBuilder() .startObject() .startObject("article") .startObject("properties") .startObject("id") .field("type", "integer").field("store", "yes") .endObject() .startObject("title") .field("type", "string").field("store", "yes").field("analyzer", "ik_smart") .endObject() .startObject("content") .field("type", "string").field("store", "yes").field("analyzer", "ik_smart") .endObject() .endObject() .endObject() .endObject(); // 创建映射 PutMappingRequest mapping = Requests.putMappingRequest("blog2") .type("article").source(builder); client.admin().indices().putMapping(mapping).get(); //释放资源 client.close(); }4 建立文档document@Test //创建文档(通过XContentBuilder) public void test4() throws Exception{ // 创建Client连接对象 Settings settings = Settings.builder().put("cluster.name", "my-elasticsearch").build(); TransportClient client = new PreBuiltTransportClient(settings) .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300)); //创建文档信息 XContentBuilder builder = XContentFactory.jsonBuilder() .startObject() .field("id", 1) .field("title", "ElasticSearch是一个基于Lucene的搜索服务器") .field("content", "它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。") .endObject(); // 建立文档对象 /** * 参数一blog1:表示索引对象 * 参数二article:类型 * 参数三1:建立id */ client.prepareIndex("blog2", "article", "1").setSource(builder).get(); //释放资源 client.close(); }5 查询文档操作5.1关键词查询@Test public void testTermQuery() throws Exception{ //1、创建es客户端连接对象 Settings settings = Settings.builder().put("cluster.name", "my-elasticsearch").build(); TransportClient client = new PreBuiltTransportClient(settings) .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300)); //2、设置搜索条件 SearchResponse searchResponse = client.prepareSearch("blog2") .setTypes("article") .setQuery(QueryBuilders.termQuery("content", "搜索")).get(); //3、遍历搜索结果数据 SearchHits hits = searchResponse.getHits(); // 获取命中次数,查询结果有多少对象 System.out.println("查询结果有:" + hits.getTotalHits() + "条"); Iterator<SearchHit> iterator = hits.iterator(); while (iterator.hasNext()) { SearchHit searchHit = iterator.next(); // 每个查询对象 System.out.println(searchHit.getSourceAsString()); // 获取字符串格式打印 System.out.println("title:" + searchHit.getSource().get("title")); } //4、释放资源 client.close(); }5.2 字符串查询@Test public void testStringQuery() throws Exception{ //1、创建es客户端连接对象 Settings settings = Settings.builder().put("cluster.name", "my-elasticsearch").build(); TransportClient client = new PreBuiltTransportClient(settings) .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300)); //2、设置搜索条件 SearchResponse searchResponse = client.prepareSearch("blog2") .setTypes("article") .setQuery(QueryBuilders.queryStringQuery("搜索")).get(); //3、遍历搜索结果数据 SearchHits hits = searchResponse.getHits(); // 获取命中次数,查询结果有多少对象 System.out.println("查询结果有:" + hits.getTotalHits() + "条"); Iterator<SearchHit> iterator = hits.iterator(); while (iterator.hasNext()) { SearchHit searchHit = iterator.next(); // 每个查询对象 System.out.println(searchHit.getSourceAsString()); // 获取字符串格式打印 System.out.println("title:" + searchHit.getSource().get("title")); } //4、释放资源 client.close(); } 5.3 使用文档ID查询文档@Test public void testIdQuery() throws Exception { //client对象为TransportClient对象 SearchResponse response = client.prepareSearch("blog1") .setTypes("article") //设置要查询的id .setQuery(QueryBuilders.idsQuery().addIds("test002")) //执行查询 .get(); //取查询结果 SearchHits searchHits = response.getHits(); //取查询结果总记录数 System.out.println(searchHits.getTotalHits()); Iterator<SearchHit> hitIterator = searchHits.iterator(); while(hitIterator.hasNext()) { SearchHit searchHit = hitIterator.next(); //打印整行数据 System.out.println(searchHit.getSourceAsString()); } }6 查询文档分页操作@Test //分页查询 public void test10() throws Exception{ // 创建Client连接对象 Settings settings = Settings.builder().put("cluster.name", "my-elasticsearch").build(); TransportClient client = new PreBuiltTransportClient(settings) .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300)); // 搜索数据 SearchRequestBuilder searchRequestBuilder = client.prepareSearch("blog2").setTypes("article") .setQuery(QueryBuilders.matchAllQuery());//默认每页10条记录 // 查询第2页数据,每页20条 //setFrom():从第几条开始检索,默认是0。 //setSize():每页最多显示的记录数。 searchRequestBuilder.setFrom(0).setSize(5); SearchResponse searchResponse = searchRequestBuilder.get(); SearchHits hits = searchResponse.getHits(); // 获取命中次数,查询结果有多少对象 System.out.println("查询结果有:" + hits.getTotalHits() + "条"); Iterator<SearchHit> iterator = hits.iterator(); while (iterator.hasNext()) { SearchHit searchHit = iterator.next(); // 每个查询对象 System.out.println(searchHit.getSourceAsString()); // 获取字符串格式打印 System.out.println("id:" + searchHit.getSource().get("id")); System.out.println("title:" + searchHit.getSource().get("title")); System.out.println("content:" + searchHit.getSource().get("content")); System.out.println("-----------------------------------------"); } //释放资源 client.close(); }7.查询结果高亮显示@Test //高亮查询 public void test11() throws Exception{ // 创建Client连接对象 Settings settings = Settings.builder().put("cluster.name", "my-elasticsearch").build(); TransportClient client = new PreBuiltTransportClient(settings) .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300)); // 搜索数据 SearchRequestBuilder searchRequestBuilder = client .prepareSearch("blog2").setTypes("article") .setQuery(QueryBuilders.termQuery("title", "搜索")); //设置高亮数据 HighlightBuilder hiBuilder=new HighlightBuilder(); hiBuilder.preTags("<font style='color:red'>"); hiBuilder.postTags("</font>"); hiBuilder.field("title"); searchRequestBuilder.highlighter(hiBuilder); //获得查询结果数据 SearchResponse searchResponse = searchRequestBuilder.get(); //获取查询结果集 SearchHits searchHits = searchResponse.getHits(); System.out.println("共搜到:"+searchHits.getTotalHits()+"条结果!"); //遍历结果 for(SearchHit hit:searchHits){ System.out.println("String方式打印文档搜索内容:"); System.out.println(hit.getSourceAsString()); System.out.println("Map方式打印高亮内容"); System.out.println(hit.getHighlightFields()); System.out.println("遍历高亮集合,打印高亮片段:"); Text[] text = hit.getHighlightFields().get("title").getFragments(); for (Text str : text) { System.out.println(str); } } //释放资源 client.close(); }
-
概述Elasticsearch是面向文档(document oriented)的,这意味着它可以存储整个对象或文档(document)。然而它不仅仅是存储,还会索引(index)每个文档的内容使之可以被搜索。在Elasticsearch中,你可以对文档(而非成行成列的数据)进行索引、搜索、排序、过滤。 ElasticSearch的官方地址: cid:link_0Elasticsearch核心概念1 索引 index一个索引就是一个拥有几分相似特征的文档的集合。比如说,你可以有一个客户数据的索引,另一个产品目录的索引,还有一个订单数据的索引。一个索引由一个名字来标识(必须全部是小写字母的),并且当我们要对对应于这个索引中的文档进行索引、搜索、更新和删除的时候,都要使用到这个名字。在一个集群中,可以定义任意多的索引。2 类型 type在一个索引中,你可以定义一种或多种类型。一个类型是你的索引的一个逻辑上的分类/分区,其语义完全由你来定。通常,会为具有一组共同字段的文档定义一个类型。比如说,我们假设你运营一个博客平台并且将你所有的数据存储到一个索引中。在这个索引中,你可以为用户数据定义一个类型,为博客数据定义另一个类型,当然,也可以为评论数据定义另一个类型。3 字段Field相当于是数据表的字段,对文档数据根据不同属性进行的分类标识4 映射 mappingmapping是处理数据的方式和规则方面做一些限制,如某个字段的数据类型、默认值、分析器、是否被索引等等,这些都是映射里面可以设置的,其它就是处理es里面数据的一些使用规则设置也叫做映射,按着最优规则处理数据对性能提高很大,因此才需要建立映射,并且需要思考如何建立映射才能对性能更好。5 文档 document一个文档是一个可被索引的基础信息单元。比如,你可以拥有某一个客户的文档,某一个产品的一个文档,当然,也可以拥有某个订单的一个文档。文档以JSON(Javascript Object Notation)格式来表示,而JSON是一个到处存在的互联网数据交互格式。在一个index/type里面,你可以存储任意多的文档。注意,尽管一个文档,物理上存在于一个索引之中,文档必须被索引/赋予一个索引的type。6 接近实时 NRTElasticsearch是一个接近实时的搜索平台。这意味着,从索引一个文档直到这个文档能够被搜索到有一个轻微的延迟(通常是1秒以内)7 集群 cluster一个集群就是由一个或多个节点组织在一起,它们共同持有整个的数据,并一起提供索引和搜索功能。一个集群由一个唯一的名字标识,这个名字默认就是“elasticsearch”。这个名字是重要的,因为一个节点只能通过指定某个集群的名字,来加入这个集群8 节点 node一个节点是集群中的一个服务器,作为集群的一部分,它存储数据,参与集群的索引和搜索功能。和集群类似,一个节点也是由一个名字来标识的,默认情况下,这个名字是一个随机的漫威漫画角色的名字,这个名字会在启动的时候赋予节点。这个名字对于管理工作来说挺重要的,因为在这个管理过程中,你会去确定网络中的哪些服务器对应于Elasticsearch集群中的哪些节点。一个节点可以通过配置集群名称的方式来加入一个指定的集群。默认情况下,每个节点都会被安排加入到一个叫做“elasticsearch”的集群中,这意味着,如果你在你的网络中启动了若干个节点,并假定它们能够相互发现彼此,它们将会自动地形成并加入到一个叫做“elasticsearch”的集群中。在一个集群里,只要你想,可以拥有任意多个节点。而且,如果当前你的网络中没有运行任何Elasticsearch节点,这时启动一个节点,会默认创建并加入一个叫做“elasticsearch”的集群。9 分片和复制 shards&replicas一个索引可以存储超出单个结点硬件限制的大量数据。比如,一个具有10亿文档的索引占据1TB的磁盘空间,而任一节点都没有这样大的磁盘空间;或者单个节点处理搜索请求,响应太慢。为了解决这个问题,Elasticsearch提供了将索引划分成多份的能力,这些份就叫做分片。当你创建一个索引的时候,你可以指定你想要的分片的数量。每个分片本身也是一个功能完善并且独立的“索引”,这个“索引”可以被放置到集群中的任何节点上。分片很重要,主要有两方面的原因: 1)允许你水平分割/扩展你的内容容量。 2)允许你在分片(潜在地,位于多个节点上)之上进行分布式的、并行的操作,进而提高性能/吞吐量。至于一个分片怎样分布,它的文档怎样聚合回搜索请求,是完全由Elasticsearch管理的,对于作为用户的你来说,这些都是透明的。在一个网络/云的环境里,失败随时都可能发生,在某个分片/节点不知怎么的就处于离线状态,或者由于任何原因消失了,这种情况下,有一个故障转移机制是非常有用并且是强烈推荐的。为此目的,Elasticsearch允许你创建分片的一份或多份拷贝,这些拷贝叫做复制分片,或者直接叫复制。复制之所以重要,有两个主要原因: 在分片/节点失败的情况下,提供了高可用性。因为这个原因,注意到复制分片从不与原/主要(original/primary)分片置于同一节点上是非常重要的。扩展你的搜索量/吞吐量,因为搜索可以在所有的复制上并行运行。总之,每个索引可以被分成多个分片。一个索引也可以被复制0次(意思是没有复制)或多次。一旦复制了,每个索引就有了主分片(作为复制源的原来的分片)和复制分片(主分片的拷贝)之别。分片和复制的数量可以在索引创建的时候指定。在索引创建之后,你可以在任何时候动态地改变复制的数量,但是你事后不能改变分片的数量。默认情况下,Elasticsearch中的每个索引被分片5个主分片和1个复制,这意味着,如果你的集群中至少有两个节点,你的索引将会有5个主分片和另外5个复制分片(1个完全拷贝),这样的话每个索引总共就有10个分片。设计方案ES 订单数据的同步方案 MySQL数据同步到ES中,大致总结可以分为两种方案:方案1:监听MySQL的Binlog,分析Binlog将数据同步到ES集群中。方案2:直接通过ES API将数据写入到ES集群中。考虑到订单系统ES服务的业务特殊性,对于订单数据的实时性较高,显然监听Binlog的方式相当于异步同步,有可能会产生较大的延时性。且方案1实质上跟方案2类似,但又引入了新的系统,维护成本也增高。所以订单中心ES采用了直接通过ES API写入订单数据的方式,该方式简洁灵活,能够很好的满足订单中心数据同步到ES的需求。由于ES订单数据的同步采用的是在业务中写入的方式,当新建或更新文档发生异常时,如果重试势必会影响业务正常操作的响应时间。所以每次业务操作只更新一次ES,如果发生错误或者异常,在数据库中插入一条补救任务,有Worker任务会实时地扫这些数据,以数据库订单数据为基准来再次更新ES数据。通过此种补偿机制,来保证ES数据与数据库订单数据的最终一致性。IK 分词器和ElasticSearch集成使用IK分词器简介IKAnalyzer是一个开源的,基于java语言开发的轻量级的中文分词工具包。从2006年12月推出1.0版开始,IKAnalyzer已经推出 了3个大版本。最初,它是以开源项目Lucene为应用主体的,结合词典分词和文法分析算法的中文分词组件。新版本的IKAnalyzer3.0则发展为 面向Java的公用分词组件,独立于Lucene项目,同时提供了对Lucene的默认优化实现。IK分词器3.0的特性如下:1)采用了特有的“正向迭代最细粒度切分算法“,具有60万字/秒的高速处理能力。2)采用了多子处理器分析模式,支持:英文字母(IP地址、Email、URL)、数字(日期,常用中文数量词,罗马数字,科学计数法),中文词汇(姓名、地名处理)等分词处理。3)对中英联合支持不是很好,在这方面的处理比较麻烦.需再做一次查询,同时是支持个人词条的优化的词典存储,更小的内存占用。4)支持用户词典扩展定义。5)针对Lucene全文检索优化的查询分析器IKQueryParser;采用歧义分析算法优化查询关键字的搜索排列组合,能极大的提高Lucene检索的命中率。
推荐直播
-
HDC深度解读系列 - Serverless与MCP融合创新,构建AI应用全新智能中枢2025/08/20 周三 16:30-18:00
张昆鹏 HCDG北京核心组代表
HDC2025期间,华为云展示了Serverless与MCP融合创新的解决方案,本期访谈直播,由华为云开发者专家(HCDE)兼华为云开发者社区组织HCDG北京核心组代表张鹏先生主持,华为云PaaS服务产品部 Serverless总监Ewen为大家深度解读华为云Serverless与MCP如何融合构建AI应用全新智能中枢
回顾中 -
关于RISC-V生态发展的思考2025/09/02 周二 17:00-18:00
中国科学院计算技术研究所副所长包云岗教授
中科院包云岗老师将在本次直播中,探讨处理器生态的关键要素及其联系,分享过去几年推动RISC-V生态建设实践过程中的经验与教训。
回顾中 -
一键搞定华为云万级资源,3步轻松管理企业成本2025/09/09 周二 15:00-16:00
阿言 华为云交易产品经理
本直播重点介绍如何一键续费万级资源,3步轻松管理成本,帮助提升日常管理效率!
回顾中
热门标签