学成线上 微服务 第10-3天全文检索 Elasticearch 研究 搜寻管理
7搜寻管理
7.1准备环境7.1.1建立对映
建立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"
}
}
}
7.1.2插入原始资料
向xc_course/doc中插入以下资料:
参考 “资料”–》搜寻测试-初始化资料.txt
http://localhost:9200/xc_course/doc/1
{
"name": "Bootstrap开发",
"description": "Bootstrap是由Twitter推出的一个前台页面开发框架,是一个非常流行的开发框架,此框架集成了多种页面效果。此开发框架包含了大量的CSS、JS程式程式码,可以帮助开发者(尤其是不擅长页面开发的程式人员)轻松 的实现一个不受浏览器限制的精美界面效果。",
"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"
}
7.1.3简单搜寻
简单搜寻就是通过url进行查询,以get方式请求ES。 格式:get …/_search?q=…
q:搜寻字串。
例子:
?q=name:spring 搜寻name中包括spring的文件。
7.3DSL搜寻
DSL(Domain Specific Language)是ES提出的基于json的搜寻方式,在搜寻时传入特定的json格式的资料来完成不同的搜寻需求。
DSL比URI搜寻方式功能强大,在专案中建议使用DSL方式来完成搜寻。
7.3.1查询所有文件
查询所有索引库的文件。
传送: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 {
SearchRequest searchRequest = new SearchRequest("xc_course"); searchRequest.types("doc");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); searchSourceBuilder.query(QueryBuilders.matchAllQuery());
//source源字段过虑
searchSourceBuilder.fetchSource(new String[]{"name","studymodel"}, new String[]{});
searchRequest.source(searchSourceBuilder);
SearchResponse searchResponse = client.search(searchRequest);
SearchHits hits = searchResponse.getHits(); SearchHit[] searchHits = hits.getHits(); for (SearchHit hit : searchHits) {
String index = hit.getIndex(); String type = hit.getType(); String id = hit.getId();
float score = hit.getScore();
String sourceAsString = hit.getSourceAsString(); Map sourceAsMap = hit.getSourceAsMap(); String name = (String) sourceAsMap.get("name");
String studymodel = (String) sourceAsMap.get("studymodel"); String description = (String) sourceAsMap.get("description"); System.out.println(name);
System.out.println(studymodel); System.out.println(description);
}
}
7.3.2分页查询
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
SearchRequest searchRequest = new SearchRequest("xc_course"); searchRequest.types("xc_course");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); searchSourceBuilder.query(QueryBuilders.matchAllQuery());
//分页查询,设定起始下标,从0开始
searchSourceBuilder.from(0);
//每页显示个数searchSourceBuilder.size(10);
//source源字段过虑
searchSourceBuilder.fetchSource(new String[]{"name","studymodel"}, new String[]{}); searchRequest.source(searchSourceBuilder);
SearchResponse searchResponse = client.search(searchRequest);
7.3.3Term Query
Term Query为精确查询,在搜寻时会整体匹配关键字,不再将关键字分词。传送:post http://localhost:9200/xc_course/doc/_search
{
"query": {
"term" : {
"name": "spring"
}
},
"_source" : ["name","studymodel"]
}
上边的搜寻会查询name包括“spring”这个词的文件。
SearchRequest searchRequest = new SearchRequest("xc_course"); searchRequest.types("xc_course");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); searchSourceBuilder.query(QueryBuilders.termQuery("name","spring"));
//source源字段过虑
searchSourceBuilder.fetchSource(new String[]{"name","studymodel"}, new String[]{}); searchRequest.source(searchSourceBuilder);
SearchResponse searchResponse = client.search(searchRequest);
7.3.4根据id精确匹配
ES提供根据多个id值匹配的方法: 测试:
post: http://127.0.0.1:9200/xc_course/doc/_search
{
"query": {
"ids" : {
"type" : "doc",
"values" : ["3", "4", "100"]
}
}
}
JavaClient:
String[] split = new String[]{"1","2"}; List idList = Arrays.asList(split);
searchSourceBuilder.query(QueryBuilders.termsQuery("_id", idList));
7.3.5match Query
1、基本使用
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 {
SearchRequest searchRequest = new SearchRequest("xc_course"); searchRequest.types("xc_course");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//source源字段过虑
searchSourceBuilder.fetchSource(new String[]{"name","studymodel"}, new String[]{});
// 匹 配 关 键 字 searchSourceBuilder.query(QueryBuilders.matchQuery("description", "spring 开
发").operator(Operator.OR));
searchRequest.source(searchSourceBuilder);
SearchResponse searchResponse = client.search(searchRequest); SearchHits hits = searchResponse.getHits();
SearchHit[] searchHits = hits.getHits(); for (SearchHit hit : searchHits) {
String index = hit.getIndex(); String type = hit.getType(); String id = hit.getId();
float score = hit.getScore();
String sourceAsString = hit.getSourceAsString(); Map sourceAsMap = hit.getSourceAsMap(); String name = (String) sourceAsMap.get("name");
String studymodel = (String) sourceAsMap.get("studymodel"); String description = (String) sourceAsMap.get("description"); 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如下:
//匹配关键字
MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("description", "前台页面开发框架 架构")
.minimumShouldMatch("80%");//设定匹配占比
searchSourceBuilder.query(matchQueryBuilder);
7.3.6multi 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 框 架 ", "minimum_should_match": "50%", "fields": [ "name", "description" ]
}
}
}
通过查询发现Bootstrap排在前边。
提升boost,通常关键字匹配上name的权重要比匹配上description的权重高,这里可以对name的权重提升。
{
"query": {
"multi_match" : {
"query" : "spring 框 架 ", "minimum_should_match": "50%", "fields": [ "name^10", "description" ]
}
}
}
“name^10” 表示权重提升10倍,执行上边的查询,发现name中包括spring关键字的文件排在前边。
JavaClient:
MultiMatchQueryBuilder multiMatchQueryBuilder = QueryBuilders.multiMatchQuery("spring框架", "name", "description")
.minimumShouldMatch("50%"); multiMatchQueryBuilder.field("name",10);//提升boost
7.3.7布林查询
布林查询对应于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 框 架 ", "minimum_should_match": "50%", "fields": [ "name^10", "description" ]
}
},
{
"term":{
"studymodel" : "201001"
}
}
]
}
}
}
must:表示必须,多个查询条件必须都满足。(通常使用must) should:表示或者,多个查询条件只要有一个满足即可。must_not:表示非。
JavaClient:
//BoolQuery,将搜寻关键字分词,拿分词去索引库搜寻@Test
public void testBoolQuery() throws IOException {
//建立搜寻请求物件
SearchRequest searchRequest= new SearchRequest("xc_course"); searchRequest.types("doc");
//建立搜寻源配置物件
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); searchSourceBuilder.fetchSource(new String[]{"name","pic","studymodel"},new String[]{});
//multiQuery
String keyword = "spring开发框架";
MultiMatchQueryBuilder multiMatchQueryBuilder = QueryBuilders.multiMatchQuery("spring框架",
"name", "description")
.minimumShouldMatch("50%"); multiMatchQueryBuilder.field("name",10);
//TermQuery
TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("studymodel", "201001");
//布林查询
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery(); boolQueryBuilder.must(multiMatchQueryBuilder); boolQueryBuilder.must(termQueryBuilder);
//设定布林查询物件
searchSourceBuilder.query(boolQueryBuilder); searchRequest.source(searchSourceBuilder);//设定搜寻源配置
SearchResponse searchResponse = client.search(searchRequest); SearchHits hits = searchResponse.getHits();
SearchHit[] searchHits = hits.getHits(); for(SearchHit hit:searchHits){
Map sourceAsMap = hit.getSourceAsMap(); System.out.println(sourceAsMap);
}
}
7.3.8过虑器
过虑是针对搜寻的结果进行过虑,过虑器主要判断的是文件是否匹配,不去计算和判断文件的匹配度得分,所以过 虑器效能比查询要高,且方便快取,推荐尽量使用过虑器去实现查询或者过虑器和查询共同使用。
过虑器在布林查询中使用,下边是在搜寻结果的基础上进行过虑:
{"_source" : [ "name", "studymodel", "description","price"],
"query": {
"bool" : {
"must":[
{
"multi_match" : { "query" : "spring 框 架 ", "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:
//布林查询使用过虑器
@Test
public void testFilter() throws IOException {
SearchRequest searchRequest = new SearchRequest("xc_course"); searchRequest.types("doc");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//source源字段过虑
searchSourceBuilder.fetchSource(new String[]{"name","studymodel","price","description"}, new String[]{});
searchRequest.source(searchSourceBuilder);
//匹配关键字
MultiMatchQueryBuilder multiMatchQueryBuilder = QueryBuilders.multiMatchQuery("spring框架 ", "name", "description");
//设定匹配占比
multiMatchQueryBuilder.minimumShouldMatch("50%");
//提升另个字段的Boost值multiMatchQueryBuilder.field("name",10); searchSourceBuilder.query(multiMatchQueryBuilder);
//布林查询
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery(); boolQueryBuilder.must(searchSourceBuilder.query());
//过虑
boolQueryBuilder.filter(QueryBuilders.termQuery("studymodel", "201001")); boolQueryBuilder.filter(QueryBuilders.rangeQuery("price").gte(60).lte(100));
SearchResponse searchResponse = client.search(searchRequest); SearchHits hits = searchResponse.getHits();
SearchHit[] searchHits = hits.getHits(); for (SearchHit hit : searchHits) {
String index = hit.getIndex(); String type = hit.getType(); String id = hit.getId();
float score = hit.getScore();
String sourceAsString = hit.getSourceAsString(); Map sourceAsMap = hit.getSourceAsMap(); String name = (String) sourceAsMap.get("name");
String studymodel = (String) sourceAsMap.get("studymodel"); String description = (String) sourceAsMap.get("description"); System.out.println(name);
System.out.println(studymodel); System.out.println(description);
}
}
7.3.9排序
可以在字段上新增一个或多个排序,支援在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:
@Test
public void testSort() throws IOException {
SearchRequest searchRequest = new SearchRequest("xc_course"); searchRequest.types("doc");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//source源字段过虑
searchSourceBuilder.fetchSource(new String[]{"name","studymodel","price","description"}, new String[]{});
searchRequest.source(searchSourceBuilder);
//布林查询
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
//过虑boolQueryBuilder.filter(QueryBuilders.rangeQuery("price").gte(0).lte(100));
//排序
searchSourceBuilder.sort(new FieldSortBuilder("studymodel").order(SortOrder.DESC)); searchSourceBuilder.sort(new FieldSortBuilder("price").order(SortOrder.ASC));
SearchResponse searchResponse = client.search(searchRequest); SearchHits hits = searchResponse.getHits();
SearchHit[] searchHits = hits.getHits(); for (SearchHit hit : searchHits) {
String index = hit.getIndex(); String type = hit.getType(); String id = hit.getId();
float score = hit.getScore();
String sourceAsString = hit.getSourceAsString(); Map sourceAsMap = hit.getSourceAsMap(); String name = (String) sourceAsMap.get("name");
String studymodel = (String) sourceAsMap.get("studymodel"); String description = (String) sourceAsMap.get("description"); System.out.println(name);
System.out.println(studymodel); System.out.println(description);
}
}
7.3.10高亮显示
高亮显示可以将搜寻结果一个或多个字突出显示,以便向用户展示匹配关键字的位置。 在搜寻语句中新增highlight即可实现,如下:
Post: http://127.0.0.1:9200/xc_course/doc/_search
{
"_source" : [ "name", "studymodel", "description","price"],
"query": {
"bool" : {
"must":[
{
"multi_match" : { "query" : " 开 发 框 架 ", "minimum_should_match": "50%", "fields": [ "name^10", "description" ], "type":"best_fields"
}
}
],
"filter": [
{ "range": { "price": { "gte": 0 ,"lte" : 100}}}
]
}
},
"sort" : [
{
"price" : "asc"
}
],
"highlight": { "pre_tags": [""],
"post_tags": [""], "fields": {
"name": {},
"description":{}
}
}
}
client程式码如下:
@Test
public void testHighlight() throws IOException {
SearchRequest searchRequest = new SearchRequest("xc_course"); searchRequest.types("doc");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//source源字段过虑
searchSourceBuilder.fetchSource(new String[]{"name","studymodel","price","description"}, new String[]{});
searchRequest.source(searchSourceBuilder);
//匹配关键字
MultiMatchQueryBuilder multiMatchQueryBuilder = QueryBuilders.multiMatchQuery("开发",
"name", "description");
searchSourceBuilder.query(multiMatchQueryBuilder);
//布林查询
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery(); boolQueryBuilder.must(searchSourceBuilder.query());
//过虑boolQueryBuilder.filter(QueryBuilders.rangeQuery("price").gte(0).lte(100));
//排序
searchSourceBuilder.sort(new FieldSortBuilder("studymodel").order(SortOrder.DESC)); searchSourceBuilder.sort(new FieldSortBuilder("price").order(SortOrder.ASC));
//高亮设定
HighlightBuilder highlightBuilder = new HighlightBuilder(); highlightBuilder.preTags("");//设定字首highlightBuilder.postTags("");//设定字尾
// 设定高亮字段
highlightBuilder.fields().add(new HighlightBuilder.Field("name"));
//highlightBuilder.fields().add(new HighlightBuilder.Field("description")); searchSourceBuilder.highlighter(highlightBuilder);
SearchResponse searchResponse = client.search(searchRequest);
SearchHits hits = searchResponse.getHits();
SearchHit[] searchHits = hits.getHits(); for (SearchHit hit : searchHits) {
Map sourceAsMap = hit.getSourceAsMap();
//名称
String name = (String) sourceAsMap.get("name");
//取出高亮字段内容
Map highlightFields = hit.getHighlightFields(); if(highlightFields!=null){
HighlightField nameField = highlightFields.get("name"); if(nameField!=null){
Text[] fragments = nameField.getFragments(); StringBuffer stringBuffer = new StringBuffer(); for (Text str : fragments) {
stringBuffer.append(str.string());
}
name = stringBuffer.toString();
}
}
String index = hit.getIndex(); String type = hit.getType(); String id = hit.getId();
float score = hit.getScore();
String sourceAsString = hit.getSourceAsString();
String studymodel = (String) sourceAsMap.get("studymodel"); String description = (String) sourceAsMap.get("description"); System.out.println(name);
System.out.println(studymodel); System.out.println(description);
}
}
8丛集管理
8.1丛集结构ES通常以丛集方式工作,这样做不仅能够提高 ES的搜寻能力还可以处理大资料搜寻的能力,同时也增加了系统的容错能力及高可用,ES可以实现PB级资料的搜寻。
下图是ES丛集结构的示意图:

从上图总结以下概念:
1、结点
ES丛集由多个服务器组成,每个服务器即为一个Node结点(该服务只部署了一个ES程序)。 2、分片
当我们的文件量很大时,由于内存和硬盘的限制,同时也为了提高ES的处理能力、容错能力及高可用能力,我们将 索引分成若干分片,每个分片可以放在不同的服务器,这样就实现了多个服务器共同对外提供索引及搜寻服务。
一个搜寻请求过来,会分别从各各分片去查询,最后将查询到的资料合并返回给使用者。
3、副本
为了提高ES的高可用同时也为了提高搜寻的吞吐量,我们将分片复制一份或多份储存在其它的服务器,这样即使当 前的服务器挂掉了,拥有副本的服务器照常可以提供服务。
4、主结点
一个丛集中会有一个或多个主结点,主结点的作用是丛集管理,比如增加节点,移除节点等,主结点挂掉后ES会重 新选一个主结点。
5、结点转发
每个结点都知道其它结点的资讯,我们可以对任意一个结点发起请求,接收请求的结点会转发给其它结点查询数 据。
8.2搭建丛集
下边的例子实现建立一个2结点的丛集,并且索引的分片我们设定2片,每片一个副本。
8.2.1结点的三个角色
主结点: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表示它是一个客户端。
8.2.2建立结点 1
解压elasticsearch-6.2.1.zip 到 F:devenvelasticsearches-cloud-1elasticsearch-6.2.1
结点1对外服务的http埠是:9200 丛集管理埠是9300
配置elasticsearch.yml
结 点 名 :xc_node_1 elasticsearch.yml内容如下
cluster.name: xuecheng node.name: xc_node_1 network.host: 0.0.0.0
http.port: 9200
transport.tcp.port: 9300 node.master: true node.data: true
discovery.zen.ping.unicast.hosts: ["0.0.0.0:9300", "0.0.0.0:9301"]
discovery.zen.minimum_master_nodes: 1 node.ingest: true node.max_local_storage_nodes: 2
path.data: D:ElasticSearchelasticsearch‐6.2.1‐1data path.logs: D:ElasticSearchelasticsearch‐6.2.1‐1logs http.cors.enabled: true
http.cors.allow‐origin: /.*/
启动结点1
8.2.3建立结点 2
解压elasticsearch-6.2.1.zip 到 F:devenvelasticsearches-cloud-2elasticsearch-6.2.1
结点1对外服务的http埠是:9201 丛集管理埠是9302
结点名:xc_node_2
elasticsearch.yml内容如下
cluster.name: xuecheng node.name: xc_node_2 network.host: 0.0.0.0
http.port: 9201
transport.tcp.port: 9301 node.master: true node.data: true
discovery.zen.ping.unicast.hosts: ["0.0.0.0:9300", "0.0.0.0:9301"]
discovery.zen.minimum_master_nodes: 1
node.ingest: true node.max_local_storage_nodes: 2
path.data: D:ElasticSearchelasticsearch‐6.2.1‐2data path.logs: D:ElasticSearchelasticsearch‐6.2.1‐2logs http.cors.enabled: true
http.cors.allow‐origin: /.*/
启动结点2
8.2.4建立索引库
1)使用head连上其中一个结点

上图表示两个结点已经建立成功。
2)下边建立索引库,共2个分片,每个分片一个副本。

建立成功,重新整理head:

上图可以看到共有4个分片,其中两个分片是副本。
3)每个结点安装IK分词器略
8.2.5丛集的健康
通过访问 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
}
8.3测试
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
全部资料可被正常搜寻到。