ElasticSearch再学习

ElasticSearch参数详解

本次使用的windows的版本,如若Linux移步:https://www.cnblogs.com/msi-chen/p/10335794.html

 

配置文件参数

首先我们对ES的解压目录做一个简单的了解:

  

然后就是配置文件目录中的三个配置文件做一个说明:

  • elasticsearch.yml

    点击进去里面的配置全是被注释掉的,我们可以加入下面的数据作为配置

  • jvm.options

    有关JVM属性的配置,一般我们就设置堆的最小最大值,一般设为相等,不能超过物理内存的一半

    -Xms2g -Xmx2g

  • log4j2.properties

    日志文件的配置,ES使用log4j,配置一下日志级别就OK

面向Restful的api接口

  • 创建索引库

    put http://localhost:9200/索引库名称

    • number_of_shards:设置分片的数量,在集群中通常设置多个分片,表示一个索引库将拆分成多片分别存储不同的结点,提高了ES的处理能力和高可用性,入门程序使用单机环境,这里设置为1。

    • number_of_replicas:设置副本的数量,设置副本是为了提高ES的高可靠性,单机环境设置为0.

  • 创建映射

    post http://localhost:9200/索引库名称/类型名称/_mapping

    • 类型名称暂时没有意义存在,随便取一个即可,比如doc这种没有意义的

  • 插入文档

    put 或Post http://localhost:9200/索引库名称/类型名称/文档id

    关于最后的文档id,我们如果有设置就会使用我们自己的,若不设置,ES会自动生成

  • 搜索文档

    根据文档id查询:

    查询所有文档:

    根据某个属性的的值插叙:

    • get http://localhost:9200/索引库名称/类型名称/_search?q=name:bootstrap

    • 根据name属性的值为bootstrap进行查询,前面固定格式

  • 查询结果参数解析

    查询结果一般会有如下数据显示

IK分词器

简单上手

ES默认自带的分词器对于中文而言是单字分词,比如我爱祖国,ES会一个字一个字的分词,这样很明显不行

我们查看下面的分词效果

post:localhost:9200/_analyze

{"text":"测试分词器,我爱祖国"}

ES在之前的文件目录说明哪里也有说到,ES是支持插件机制的,我们将IK丢pligins包里就好,记得重启ES

我们手动指定使用的分词器,查看下面的分词效果

post:localhost:9200/_analyze

{"text":"测试分词器,我爱我自己","analyzer":"ik_max_word"}

然后发现好像有点复合我们国人的口味了,这里ik分词有两个模式

  • ik_max_word ,这个就是我们上面使用到的一个模式,划分粒度比较细,一般用于存储的时候,进行分词存储索引

  • ik_smart ,相对而言,这个就要粗旷一些了,一般在检索索引时,对检索条件的字段进行粗旷的分词

    比如:下面这句话的意思就是name属性在索引和在搜索时都是用ik_max_word模式

    "name": { "type": "text", "analyzer":"ik_max_word" }

    再比如:索引时使用“ik_max_word”分词,搜索时使用“ik_smart”提高搜索精确性

    "name": { "type": "text", "analyzer":"ik_max_word", "search_analyzer":"ik_smart" }

自定义词库

有一些特殊的领域是有一些专有的词语的,而Ik是分辨不出来,所以这里需要使用到IK的自定义词库

  • 首先定义我们自己的词库:my.dic

    记得保存为UTF-8格式,不然读取不到

  • 然后我们再配置文件中去加载我们的自定义词库:IKAnalyzer.cfg.xml

  • 然后重启ES,查看分词效果

post:localhost:9200/_analyze

{"text":"死亡野格儿","analyzer":"ik_max_word"}

映射

  • 映射一旦创建,已有的映射是不允许更改,只能新增或者删除重建

  • 删除映射也只能通过删除索引来完成

映射的类型_text

核心的字段类型:

映射的类型选好了,还有一些其他的属性可以设置

  • analyzer :通过该属性指定分词器及模式

    name属性的类型为text,在索引时使用“ik_max_word”分词器模式

    在搜索时使用"ik_smart "分词器模式分词

    一般都是建议在索引的时候词语最细化,在搜索时,对搜索条件粗旷化提高搜索精度

  • index:通过该属性指定是否索引,默认为true

    只有在设置为false时,该属性的值是不会存入索引库的,也不会被检索到

    比如pic属性表示的是图片的地址,一般我们不uhi把这个地址作为搜索条件进行检索,故而设置为false

  • store:额外存储,一般不用理会

    是否在source之外存储,每个文档索引后会在 ES中保存一份原始文档,存放在"source"中,一般情况下不需要设置 store为true,因为在source中已经有一份原始文档了。

映射的类型_keyword关键字

上面我们说明了text类型的属性在映射时都可以is盒子分词器,keyword字段是一个关键字字段,通常搜索keyword是按照整体搜索的,是不会做分词,所以查询的时候是需要精确匹配的,比如邮政编码,身份证号等是不会且不应该做分词的,keywoed文本一般用于过滤,排序,聚合等场合

  • 映射如下:

  • 插入文档

  • 根据name或者身份证号查询

    Get:http://localhost:9200/索引库/类型名称/_search?q=name:狗剩儿

    这样是查询不到的,因为name属性是keyword类型,必须精确匹配

映射的类型_data日期类型

日期类型也是不用设置分词器的一种类型,一般日期类型用于排序

通过format设置日期的格式,上面的这个列子允许date字段储存年月日时分秒||年月日这两种格式

插入文档如下:Post:Post :http://localhost:9200/索引库/类型名/文档id

{ "time":"2018‐08‐15 20:28:58" }

映射的类型_数值类型

  • 尽量选择范围晓得类型,提高检索效率节省空间

  • 对于浮点数,尽量用比列因子,比如一个鸡蛋的单价是1.2元/个,我们将别列因子设置为100,这在ES中会按照分储存,映射如下:

因为我们将比列因子设置为100,所以储存的时候,会将1.2 * 100 进行储存

使用比列因子的好处就在与整型比浮点型更容易压缩,节约空间,当然如果比列因子不合适,我们再选范围小的去存

ES客户端(Java)

  • pom.xml:核心依赖

        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-high-level-client</artifactId>
            <version>6.2.1</version>
        </dependency>
        <dependency>
            <groupId>org.elasticsearch</groupId>
            <artifactId>elasticsearch</artifactId>
            <version>6.2.1</version>
        </dependency>
  • Spring容器注入客户端

    注意这里注入两个版本的客户端一个是高版本,推荐使用的RestHighLevelClient,但功能可能不是很完善

    RestClient低版本的客户端,当我们高版本的客户端不能使用时,考虑使用这个

@Configuration
public class ElasticsearchConfig {
​
    @Value("${test.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<split.length;i++){
            String item = split[i];
            httpHostArray[i] = new HttpHost(item.split(":")[0], Integer.parseInt(item.split(":")[1]), "http");
        }
        //创建RestHighLevelClient客户端
        return new RestHighLevelClient(RestClient.builder(httpHostArray));
    }
​
    //项目主要使用RestHighLevelClient,对于低级的客户端暂时不用
    @Bean
    public RestClient restClient(){
        //解析hostlist配置信息
        String[] split = hostlist.split(",");
        //创建HttpHost数组,其中存放es主机和端口的配置信息
        HttpHost[] httpHostArray = new HttpHost[split.length];
        for(int i=0;i<split.length;i++){
            String item = split[i];
            httpHostArray[i] = new HttpHost(item.split(":")[0], Integer.parseInt(item.split(":")[1]), "http");
        }
        return RestClient.builder(httpHostArray).build();
    }
}

创建索引库

首先注入Java客户端,我们使用第一个即可:

 //高版本的客户端
    @Autowired
    RestHighLevelClient highClient;
    
    //低版本的客户端
    @Autowired
    RestClient restClient;
    
    //创建索引库
    @Test
    public void CreateIndexTest() throws IOException {
        //创建索引请求对象,并设置索引名称
        CreateIndexRequest createIndexRequest = new CreateIndexRequest("test_index");
        //设置索引参数
        createIndexRequest.settings(Settings.builder().put("number_of_shards",1)
                .put("number_of_replicas",0));
        //设置映射
        createIndexRequest.mapping("doc"," {\n" +
                " \t\"properties\": {\n" +
                " \"name\": {\n" +
                " \"type\": \"text\",\n" +
                " \"analyzer\":\"ik_max_word\",\n" +
                " \"search_analyzer\":\"ik_smart\"\n" +
                " },\n" +
                " \"description\": {\n" +
                " \"type\": \"text\",\n" +
                " \"analyzer\":\"ik_max_word\",\n" +
                " \"search_analyzer\":\"ik_smart\"\n" +
                " },\n" +
                " \"studymodel\": {\n" +
                " \"type\": \"keyword\"\n" +
                " },\n" +
                " \"price\": {\n" +
                " \"type\": \"float\"\n" +
                " }\n" +
                " }\n" +
                "}", XContentType.JSON);
        //创建索引操作客户端
        IndicesClient indices = highClient.indices();
        //创建响应对象
        CreateIndexResponse createIndexResponse = indices.create(createIndexRequest);
        //得到响应结果
        boolean acknowledged = createIndexResponse.isAcknowledged();
        System.out.println(acknowledged);
    }

添加文档

查询文档

更新文档

删除文档

搜索 [ 核心用法 ]

环境准备

首先我们创建一个名为“test_index”的索引库

并创建如下索引:

插入以下数据作为测试数据:id分别为1、2、3

最基本的搜索我们前面意思使用过了:

  • 以这样的格式: get ../_search?q=.....

DSL_搜索介绍

  • DSL:"Domain Specific Language "

  • 是ES提出的基于json的搜索方式,在搜索时键入特定的json格式的数据来哇称搜索,全部POST请求

  • 一般项目中都是使用的DSL搜索

DSL_查询所有文档

@Test
    public void queryAllTest() throws IOException {
        //创建搜索请求对象,绑定索引库和类型
        SearchRequest searchRequest = new SearchRequest("test_index");
        searchRequest.types("doc");
​
        //创建:搜索源构建对象
        SearchSourceBuilder builder = new SearchSourceBuilder();
        //指定搜索方式:matchAllQuery
        builder.query(QueryBuilders.matchAllQuery());
        //设置源字段过滤,第一个数组表示要包含的字段,第二个数组表示不包括的字段
        builder.fetchSource(new String[]{"name","studymodel"},new String[]{});
        
        //向搜索请求中设置搜索源
        searchRequest.source(builder);
        //使用客户端发起搜索,获得结果
        SearchResponse searchResponse = highClient.search(searchRequest);
        //搜索结果
        SearchHits hits = searchResponse.getHits();
        //从搜索结果中得到 : 匹配分高位于前面的文档
        SearchHit[] searchHits = hits.getHits();
        for (SearchHit hit : searchHits) {
            Map<String, Object> map = hit.getSourceAsMap();
            System.out.println(map.get("name"));
            System.out.println(map.get("studymodel"));
        }
    }

使用注意事项:

  • 在我们设置源字段过滤的时候,我们只选取了着两个字段,当我们获取对结果后,也只能获取这两个字段的数据

DSL_分页查询

精确查询Term Query

Term Query为精确查询,在搜索时会整体匹配关键字,不再将关键字分词做搜索

111

111

猜你喜欢

转载自www.cnblogs.com/msi-chen/p/11403279.html