栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 前沿技术 > 云计算 > 云平台

【Elasticsearch使用教程一篇就够了】

云平台 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【Elasticsearch使用教程一篇就够了】

1.Elasticsearch 是什么?

一句话概述:Elasticsearch 是一个分布式、RESTful 风格的搜索和数据分析引擎,同时也是 Elastic Stack 的核心。

其应用于比如说全文搜索、购物推荐、附近定位推荐等。

2.Elasticsearch安装

官网下载链接:https://www.elastic.co/cn/downloads/elasticsearch

Elasticsearch 是免安装的,只需要把 zip 包解压就可以了。

1)bin 目录下是一些脚本文件,包括 Elasticsearch 的启动执行文件。
2)config 目录下是一些配置文件。
3)jdk 目录下是内置的 Java 运行环境。
4)lib 目录下是一些 Java 类库文件。
5)logs 目录下会生成一些日志文件。
6)modules 目录下是一些 Elasticsearch 的模块。
7)plugins 目录下可以放一些 Elasticsearch 的插件。

直接双击 bin 目录下的 elasticsearch.bat 文件就可以启动 Elasticsearch 服务了。

启动后输出了很多信息,只需要看启动日志中是否有started字眼,就表示启动成功了。
确认是否真正启动成功,可以在浏览器的地址栏里输入 http://localhost:9200 进行查看(9200 是 Elasticsearch 的默认端口号)。

3.安装可视化界面 Kibana

官网下载链接:https://www.elastic.co/cn/downloads/kibana
下载后解压如下图(不同版本可能不一样)

各级目录不一一解释什么意思,大家可以自行去问度娘。
启动同样跟elasticsearch的启动一样,直接点击bin目录下的kibana.bat即可启动,启动速度相对较慢一点。
当看到 [Kibana][http] http server running 的信息后,说明服务启动成功了。
验证:在浏览器地址栏输入 http://localhost:5601 查看 Kibana 的图形化界面。

4.可视化界面操作ES
  • 检查集群的健康状态

GET _cluster/health

  • 快速检查集群的健康状态

GET _cat/health?v集群的状态:Green: 所有的primary shard和所有的replica shard 都是active的Yellow:所有的primary shard都是active的但是部分replica shard不是activeRed: 不是所有的primary shard都是active的,可能会造成数据丢失
Es规定primary shard和与他对应的replica shard 不能再同一台机器上,所以当前的状态是yellow的

  • 检查集群中有哪些索引

GET _cat/indices?v

  • 在集中创建索引

PUT /index

  • 在某个索引下创建document数据
PUT /ecommerce/product/1
{
  "name": "gaolujie yagao",
  "price": 20,
  "desc": "gaolujie yaga desc",
  "tags": "meibai jieya"
} 
  • 查询某一个document的详细信息

GET /ecommerce/product/1

  • 更新document文档

i. 全量更新 (更新后可能部分列丢失)

PUT /ecommerce/product/1
{
“name” : “heimei”
}

ii. portial update(需要更新什么 就写什么)

POST /ecommerce/product/1/_update
{
“doc”:{
“name” : “heimei”
  }
}
  • 更多常见查询命令
#创建索引结构
PUT sku
{
  "mappings": {
    "doc":{
      "properties":{
        "name":{
          "type":"text",
          "analyzer":"ik_smart"
        },
        "price":{
          "type":"integer"
        },
        "image":{
          "type":"text"
        },
        "createTime":{
          "type":"date"
        },
        "spuId":{
          "type":"text"
        },
        "categoryName":{
          "type":"keyword"
        },
        "brandName":{
          "type":"keyword"
        },
        "spec":{
          "type":"object"
        },
        "saleNum":{
          "type":"integer"
        },
        "commentNum":{
          "type":"integer"
        }
      }
    }
  }
}

#增加文档
POST sku/doc
{
  "name":"华为手机",
  "price":4500,
  "spuId":"106",
  "createTime":"2019-06-25",
  "categoryName":"手机",
  "brandName":"华为",
  "saleNum":54532,
  "commentNum":32543,
  "spec":{
    "网络制式":"全网通",
    "屏幕尺寸":"6.5"
  }
}


#新增指定ID文档
PUT sku/doc/1
{
 "name":"小米电视",
  "price":3500,
  "spuId":"117",
  "createTime":"2019-06-25",
  "categoryName":"电视",
  "brandName":"小米",
  "saleNum":2332,
  "commentNum":4123,
  "spec":{
    "网络制式":"联通4G",
    "屏幕尺寸":"6.5"
  } 
}

#查询所有文档
GET /sku/_search
{
  "query": {
    "match_all": {}
  }
}

#匹配查询(单字段查询 分词查询默认为or)
GET /sku/doc/_search
{
  "query": {
    "match": {
      "name": "小米手机"
    }
  }
}

#匹配查询(精准查找)
GET /sku/doc/_search
{
  "query": {
    "match": {
      "name": {
        "query": "小米电视",
        "operator": "and"
      }
    }
  }
}

#多字段查询(multi_match)
GET /sku/_search
{
  "query": {
    "multi_match": {
      "query": "小米",
      "fields": ["name","brandName","categoryName"]
    }
  }
}

#词条匹配(term)
GET /sku/_search
{
  "query": {
    "term": {
      "price": "1000"
    }
  }
}

#多词条匹配(terms)
GET /sku/_search
{
  "query": {
    "terms": {
      "price": [
        "1000",
        "3500"
      ]
    }
  }
}


#布尔查询(bool)
#查询名称包含手机的,并且品牌为小米的。
GET /sku/_search
{
  "query": {
    "bool": {
      "must": [
        {"match": {"name": "手机"}},
        {"term": {"brandName": "小米"}}
      ]
    }
  }
}

#布尔查询(bool)
#查询名称包含手机的,或者品牌为小米的。
GET /sku/_search
{
  "query": {
    "bool": {
      "should": [
        {"match": {"name": "手机"}},
        {"term": {"brandName": "小米"}}
      ]
    }
  }
}

#过滤查询
GET /sku/_search
{
  "query": {
    "bool": {
      "filter":[
          {"match":{"brandName":"小米"}}
        ]
    }
  }
}

#分组查询
#按分组名称聚合查询,统计每个分组的数量
GET /sku/_search
{
  "size": 0,
  "aggs": {
    "sku_category": {
      "terms": {
        "field": "categoryName"
      }
    }
  }
}

5.Java 中使用 Elasticsearch

虽然有图形化界面可供我们操作,但是对于程序员来说更多的是在程序中如何使用,当然ES也提供了API供我们使用。

第一步,在项目中添加 Elasticsearch 客户端依赖:
版本号根据使用者喜好设置


     org.elasticsearch
     elasticsearch
     7.13.2
 
 
     org.elasticsearch.client
     elasticsearch-rest-high-level-client
     7.13.2
 

第二步,在SpringBoot的application.yml中添加 Elasticsearch配置:

 # Spring配置
spring:
  elasticsearch:
	 ip: 192.168.xx.xx
	 port: 9200
	 pool: 5
	 cluster:
	   name: my-application

第三步,编写ES读取配置类:

@Configuration
public class ElasticSearchConfig {
    // 获取yml中es的配置
    @Value("${spring.elasticsearch.ip}")
    String esIp;

    @Value("${spring.elasticsearch.port}")
    int esPort;

    @Value("${spring.elasticsearch.pool}")
    String esClusterPool;
    // 注册 rest高级客户端
    @Bean
    public RestHighLevelClient restHighLevelClient(){
        RestHighLevelClient client = new RestHighLevelClient(
                RestClient.builder(
                        new HttpHost(esIp,esPort,"http")
                )
        );
        return client;
    }
}

第四步,编写ES工具类:代码不免有细小错误请理解

@Slf4j
@Component
public class EsUtileService {

    @Autowired
    RestHighLevelClient restHighLevelClient;

    
    public boolean createIndex(String indexName) {
        try {
            CreateIndexRequest createIndexRequest = new CreateIndexRequest(indexName);
            CreateIndexResponse response = restHighLevelClient.indices().create(createIndexRequest, RequestOptions.DEFAULT);
            log.info("创建索引 response 值为: {}", response.toString());
            return true;
        }catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    
    public boolean existIndex(String indexName) {
        try {
            GetIndexRequest getIndexRequest = new GetIndexRequest(indexName);
            return restHighLevelClient.indices().exists(getIndexRequest, RequestOptions.DEFAULT);
        }catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    
    public boolean deleteIndex(String indexName) {
        try {
            DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest(indexName);
            AcknowledgedResponse delete = restHighLevelClient.indices().delete(deleteIndexRequest, RequestOptions.DEFAULT);
            log.info("删除索引{},返回结果为{}", indexName, delete.isAcknowledged());
            return delete.isAcknowledged();
        }catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    
    public boolean deleteDocById(String indexName, String id) {
        try {
            DeleteRequest deleteRequest = new DeleteRequest(indexName, id);
            DeleteResponse deleteResponse = restHighLevelClient.delete(deleteRequest, RequestOptions.DEFAULT);
            log.info("删除索引{}中id为{}的文档,返回结果为{}", indexName, id, deleteResponse.status().toString());
            return true;
        }catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    
    public boolean multiAddDoc(String indexName, List list) {
        try {
            BulkRequest bulkRequest = new BulkRequest();
            list.forEach(doc -> {
                String source = JSON.toJSONString(doc);
                IndexRequest indexRequest = new IndexRequest(indexName);
                indexRequest.source(source, XContentType.JSON);
                bulkRequest.add(indexRequest);
            });
            BulkResponse bulkResponse = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
            log.info("向索引{}中批量插入数据的结果为{}", indexName, !bulkResponse.hasFailures());
            return !bulkResponse.hasFailures();
        }catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return false;
    }

    
    public boolean updateDoc(String indexName, String docId, JSONObject jsonObject) {
        try {
            UpdateRequest updateRequest = new UpdateRequest(indexName, docId).doc(JSON.toJSONString(jsonObject), XContentType.JSON);
            UpdateResponse updateResponse = restHighLevelClient.update(updateRequest, RequestOptions.DEFAULT);
            int total = updateResponse.getShardInfo().getTotal();
            log.info("更新文档的影响数量为{}",total);
            return total > 0;
        }catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    
    public JSONObject queryDocById(String indexName, String docId) {
        JSONObject jsonObject = new JSONObject();
        try {
            GetRequest getRequest = new GetRequest(indexName, docId);
            GetResponse getResponse = restHighLevelClient.get(getRequest, RequestOptions.DEFAULT);
            jsonObject = (JSONObject) JSONObject.toJSON(getResponse.getSource());
        }catch (Exception e) {
            e.printStackTrace();
        }
        return jsonObject;
    }

    
    public PageResult> conditionSearch(String indexName, Integer pageNum, Integer pageSize, String highName, Map andMap, Map orMap, Map dimAndMap, Map dimOrMap) throws IOException {
        SearchRequest searchRequest = new SearchRequest(indexName);
        // 索引不存在时不报错
        searchRequest.indicesOptions(IndicesOptions.lenientExpandOpen());
        //构造搜索条件
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = buildMultiQuery(andMap, orMap, dimAndMap, dimOrMap);
        sourceBuilder.query(boolQueryBuilder);
        //高亮处理
        if (!StringUtils.isEmpty(highName)) {
            buildHighlight(sourceBuilder, highName);
        }
        //分页处理
        buildPageLimit(sourceBuilder, pageNum, pageSize);
        //超时设置
        sourceBuilder.timeout(TimeValue.timeValueSeconds(60));
        searchRequest.source(sourceBuilder);

        //执行搜索
        SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        SearchHits searchHits = searchResponse.getHits();
        List resultList = new ArrayList<>();
        for (SearchHit hit : searchHits) {
            //原始查询结果数据
            Map sourceAsMap = hit.getSourceAsMap();
            //高亮处理
            if (!StringUtils.isEmpty(highName)) {
                Map highlightFields = hit.getHighlightFields();
                HighlightField highlightField = highlightFields.get(highName);
                if (highlightField != null) {
                    Text[] fragments = highlightField.fragments();
                    StringBuilder value = new StringBuilder();
                    for (Text text : fragments) {
                        value.append(text);
                    }
                    sourceAsMap.put(highName, value.toString());
                }
            }
            JSONObject jsonObject =  JSONObject.parseObject(JSONObject.toJSONString(sourceAsMap));
            resultList.add(jsonObject);
        }

        long total = searchHits.getTotalHits().value;
        PageResult> pageResult = new PageResult<>();
        pageResult.setPageNum(pageNum);
        pageResult.setPageSize(pageSize);
        pageResult.setTotal(total);
        pageResult.setList(resultList);
        pageResult.setTotalPage(total==0?0: (int) (total % pageSize == 0 ? total / pageSize : (total / pageSize) + 1));

        return pageResult;
    }

    
    public BoolQueryBuilder buildMultiQuery(Map andMap, Map orMap, Map dimAndMap, Map dimOrMap) {
        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
        //该值为true时搜索全部
        boolean searchAllFlag = true;
        //精确查询,and
        if (!CollectionUtils.isEmpty(andMap)) {
            for (Map.Entry entry : andMap.entrySet()) {
                MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery(entry.getKey(), entry.getValue());
                boolQueryBuilder.must(matchQueryBuilder);
            }
            searchAllFlag = false;
        }
        //精确查询,or
        if (!CollectionUtils.isEmpty(orMap)) {
            for (Map.Entry entry : orMap.entrySet()) {
                MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery(entry.getKey(), entry.getValue());
                boolQueryBuilder.should(matchQueryBuilder);
            }
            searchAllFlag = false;
        }
        //模糊查询,and
        if (!CollectionUtils.isEmpty(dimAndMap)) {
            for (Map.Entry entry : dimAndMap.entrySet()) {
                WildcardQueryBuilder wildcardQueryBuilder = QueryBuilders.wildcardQuery(entry.getKey(), "*" + entry.getValue() + "*");
                boolQueryBuilder.must(wildcardQueryBuilder);
            }
            searchAllFlag = false;
        }
        //模糊查询,or
        if (!CollectionUtils.isEmpty(dimOrMap)) {
            for (Map.Entry entry : dimOrMap.entrySet()) {
                WildcardQueryBuilder wildcardQueryBuilder = QueryBuilders.wildcardQuery(entry.getKey(), "*" + entry.getValue() + "*");
                boolQueryBuilder.should(wildcardQueryBuilder);
            }
            searchAllFlag = false;
        }
        if (searchAllFlag) {
            MatchAllQueryBuilder matchAllQueryBuilder = QueryBuilders.matchAllQuery();
            boolQueryBuilder.must(matchAllQueryBuilder);
        }

        return boolQueryBuilder;
    }

    
    public void buildHighlight(SearchSourceBuilder sourceBuilder, String highName) {
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        //设置高亮字段
        highlightBuilder.field(highName);
        //多个高亮显示
        highlightBuilder.requireFieldMatch(false);
        //高亮标签前缀
        highlightBuilder.preTags("");
        //高亮标签后缀
        highlightBuilder.postTags("");

        sourceBuilder.highlighter(highlightBuilder);
    }

    
    public void buildPageLimit(SearchSourceBuilder sourceBuilder, Integer pageNum, Integer pageSize) {
        if (sourceBuilder!=null && !StringUtils.isEmpty(pageNum) && !StringUtils.isEmpty(pageSize)) {
            sourceBuilder.from(pageSize * (pageNum-1) );
            sourceBuilder.size(pageSize);
        }
    }

}


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/897628.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号