一、docker安装Elasticsearch

1、docker pull elasticsearch:指定的版本号(不指定版本号即为最新的)

2、安装es容器

docker run -di --name=**** -p 9200:9200 -p 9300:9300 elasticsearch:5.6.8

name自己自定义,9200端口(Web管理平台端口) 9300(服务默认端口)

输入虚拟机地址访问9200页面:

docker整合elk docker elastic_elasticsearch

3、配置:

3.1、登陆容器:docker exec -it 容器名 /bin/bash

3.2、进入config目录:

docker整合elk docker elastic_docker整合elk_02

3.3、 查看文件 :

root@07f22eb41bb5:/usr/share/elasticsearch/config# ls 
 
 
elasticsearch.yml log4j2.properties scripts

因为没有vi和vim编辑器命令,所有需要安装编辑器

3.3.1、设置 apt 下载源

            

docker cp ~/sources.list kkb_es:/etc/apt/sources.list

3.3.2、安装vim编辑器

                

apt-get update 
 
    
                apt-get install vim

3.3.3、修改elasticsearch.yml文件

docker整合elk docker elastic_docker_03

/etc/security/limits.conf 中的内容

docker整合elk docker elastic_java_04

3.3.5、修改/etc/sysctl.conf,追加下面内容

vm.max_map_count=655360

3.3.6、执行sysctl -p,使得内核参数马上生效

这时候Elasticsearch安装成功

二、ElasticSearch的客户端操作

实际开发中,主要有三种方式可以作为 elasticsearch 服务的客户端:

        第一种,elasticsearch-head 插件

        第二种,使用elasticsearch 提供的 Restful 接口直接访问

        第三种,使用elasticsearch 提供的 API 进行访问

2.1、elasticsearch-head

ElasticSearch 不同于 Solr 自带图形化界面,我们可以通过安装 ElasticSearch 的 head 插件,完成图形化界面的效果,完成索引数据的查看。安装插件的方式有两种,在线安装和本地安装。本文档采用本地安 装方式进行head插件的安装。 elasticsearch-5-* 以上版本安装 head 需要安装 node 和 grunt

1 )下载 head 插件: https://github.com/mobz/elasticsearch-head

2 )将 elasticsearch-head-master 压缩包解压到任意目录,但是要和 elasticsearch 的安装目录区别开

3 )下载 nodejs : https://nodejs.org/en/download/

4)将 grunt 安装为全局命令 , Grunt 是基于 Node.js 的项目构建工具

在 cmd控制台中输入如下执行命令:npm install -g grunt-cli

docker整合elk docker elastic_分词器_05

5)进入elasticsearch-head-master目录启动head,在命令提示符下输入命令:

>npm install 
     
>grunt server

这个时候输入localhost:9100  就能打开页面了

docker整合elk docker elastic_elasticsearch_06

如果不能成功连接到es服务,需要修改ElasticSearch的config目录下的配置文件: config/elasticsearch.yml,增加以下两句命令:

                http.cors.enabled: true

                http.cors.allow-origin: "*"

然后重新启动 ElasticSearch 服务。

三、IK分词器

1、简介

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 检索的命中率。

2、安装

(1) 安装 ik 分词器

IK 分词器下载地址 https://github.com/medcl/elasticsearch-analysis-ik/releases

将 ik 分词器上传到服务器上,然后解压,并改名字为 ik

unzip elasticsearch-analysis-ik-5.6.8.zip

mv elasticsearch ik

将 ik 目录拷贝到 docker 容器的 plugins 目录下

docker cp ./ik es容器的名字 : /usr/share/elasticsearch/plugins

(2)测试

docker整合elk docker elastic_docker_07

docker整合elk docker elastic_java_08

 

ik_max_word :会将文本做最细粒度的拆分

比如会将 “ 中华人民共和国人民大会堂 ” 拆分为 “ 中华人民共和国、中华人民、中华、华人、人民共

和国、人民、共和国、大会堂、大会、会堂等词语。

ik_smart :会做最粗粒度的拆分

比如会将 “ 中华人民共和国人民大会堂 ” 拆分为中华人民共和国、人民大会堂。

四、Kibana

1、下载安装

(1) 镜像下载

docker pull docker.io/kibana : 5.6.8

(2) 安装 kibana 容器

执行如下命令,开始安装 kibana 容器

docker run -it -d -e ELASTICSEARCH_URL = http : //192.168.220.100 : 9200 --name kibana

-p 5601 : 5601 kibana : 5.6.8

ELASTICSEARCH_URL= http://192.168.220.100:9200 :是指链接的 ES 地址

restart=always: 每次服务都会重启,也就是开启启动

5601:5601: 端口号

快捷键

ctrl+i 自动缩进

ctrl+enter 提交请求

down 打开自动补全菜单

enter 或 tab 选中项自动补全

esc 关闭补全菜单

(3) 访问测试

访问 http://虚拟机地址:5601 如下:

docker整合elk docker elastic_java_09

 

2、Kibana使用

1、DSL语句使用

Query DSL 是一个 Java 开源框架用于构建类型安全的 SQL 查询语句。采用 API 代替传统的拼接字符串来构造查询语句。目前Querydsl 支持的平台包括 JPA,JDO , SQL , Java Collections , RDF , Lucene ,Hibernate Search。 elasticsearch 提供了一整套基于 JSON 的 DSL 语言来定义查询

2、索引操作

(1)查询所有索引:GET /_cat/indices?v

(2)删除某个索引 :DELETE /skuinfo

(3) 新增索引 : PUT /user

(4) 创建映射 :

 

docker整合elk docker elastic_java_10

(5)新增文档数据

PUT /user/userinfo/1 
   
{ 
   
        "name":"李四", 
   
        "age":22, 
   
        "city":"深圳", 
   
        "description":"李四来自湖北武汉!" 
   
}

(6)修改数据 :

PUT /user/userinfo/1
  
{ 
  
"name":"张三丰", 
  
"description":"在武汉读书,家在武汉!在深圳工作!" 
  
}

数据查询:

( 1)查询所有数据 :GET /user/_search

(2)根据ID查询:GET /user/userinfo/2

(3)Sort排序:desc降序,asc 升序

GET /user/_search 
      
{ 
      
        "query":{ 
      
        "match_all": {} 
      
},
      
        "sort":{ 
      
        "age":{ 
      
        "order":"desc" 
      
        } 
      
     } 
      
 }

(4)分页 :

GET /user/_search 
       
{ 
       
"query":{ 
       
"match_all": {} 
       
},
       
"sort":{ 
       
"age":{ 
       
"order":"desc" 
       
} 
       
},
       
"from": 0, 
       
"size": 2 
       
}

查询模式:

(1)term 查询(不分词)

term 主要用于分词精确匹配,如字符串、数值、日期等(不适合情况: 1. 列中除英文字符外有其它值 2. 字符串值中有冒号或中文 3. 系统自带属性如 _version )

GET _search 
         
{ 
         
        "query"          :{ 
         
          "term"          :{ 
         
          "city"          :          "          武汉          " 
         
      } 
         
    } 
         
}

(2)terms 查询:

terms 跟 term 有点类似,但 terms 允许指定多个匹配条件。 如果某个字段指定了多个值,那么文档需要一起去做匹配 。

GET _search 
           
{ 
           
"query"            :{ 
           
"terms"            :{ 
           
"city"            : 
           
[ 
           
                "武汉"            , 
           
                "广州" 
           
] 
           
     } 
           
  } 
           
}

(3)match 查询(分词,广州与武汉都能查到)

GET _search 
             
{ 
             
"query": { 
             
"match": { 
             
"city": "              广州武汉              " 
             
     } 
             
 } 
             
}

(4)范围查询

#过滤-range 范围过滤 
              
#gt表示> gte表示=> 
              
#lt表示< lte表示<= 
              
GET _search 
              
{ 
              
   "query":{ 
              
   "range": { 
              
   "age": { 
              
   "gte": 30, 
              
   "lte": 57 
              
      } 
              
   } 
              
  } 
              
}

(5) bool 查询

bool 可以用来合并多个条件查询结果的布尔逻辑,它包含一下操作符:

must : 多个查询条件的完全匹配 , 相当于 and 。

must_not : 多个查询条件的相反匹配,相当于 not 。

should : 至少有一个查询条件匹配 , 相当于 or 。

     

GET _search 
                
        { 
                
        "query"                 : { 
                
        "bool"                 : { 
                
        "must"                 : [                 { 
                
        "term"                 : { 
                
        "city"                 : { 
                
        "value"                 :                  "                 深圳                 " 
                
        } 
                
        } 
                
        },
                
        { 
                
        "range"                 :{ 
                
        "age"                 :{ 
                
        "gte"                 :                 20                 , 
                
        "lte"                 :                 99 
                
        } } } ] } }}

五、java代码操作:

pom.xml 坐标

<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>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-core</artifactId>
        <version>2.8.1</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.8.1</version>
    </dependency>
    <dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-annotations</artifactId>
    <version>2.8.1</version>
    </dependency>
</dependencies>

@Beforepublic void init() throws Exception{    //1、配置setting    Settings settings = Settings.builder().put("cluster.name", "my-elasticsearch").build();    //2、产生客户端    client=new PreBuiltTransportClient(settings);
    //3、添加节点信息
    client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("192.168.110.128"),9300));
}

1、创建索引index :

@Test 
//创建索引 
                 
public                   void                   test1                  ()                   throws                   Exception 
                 { 
                 
     
                 
        //创建名称为                  blog2                  的索引 
                 
        client                  .                  admin                  ().                  indices                  (). 
                 prepareCreate 
                 ( 
                 "blog2" 
                 ). 
                 get 
                 (); 
                 
        //释放资源 
                 
        client                  .                  close                  (); 
                 
}

2、创建映射mapping

@Testpublic void  setMappings()throws Exception {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();}

3、建立文档document

@Testpublic void createDoc() throws Exception {    //1、创建客户端,上面方法已经创建完毕    //2、创建一个文档对象    XContentBuilder builder=XContentFactory.jsonBuilder();    builder.startObject()
            .field("id",2l)
            .field("title","美好生活")
            .field("content","好好努力才可以去追求想要的生活").endObject();
    //3、将文档对象添加到索引库
    client.prepareIndex()
            .setIndex("esstudy")
            .setType("article")
            .setId("2")
            .setSource(builder).get();
    client.close();

}

4、查询:

共同点的代码:

@Beforepublic void init() throws Exception{    //1、配置setting    Settings settings = Settings.builder().put("cluster.name", "my-elasticsearch").build();    //2、产生客户端    client=new PreBuiltTransportClient(settings);
    //3、添加节点信息
    client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("192.168.110.128"),9300));

}

private void search(QueryBuilder queryBuilder) {    //2、执行查询    SearchResponse searchResponse = client.prepareSearch("esstudy")            .setTypes("article")            .setQuery(queryBuilder)            .get();
    //3、取出查询结果
    SearchHits searchHits = searchResponse.getHits();
    //4、取出查询结果的总记录数
    System.out.println("查询结果总记录数:" + searchHits.getTotalHits());
    //5、查询结果列表
    Iterator<SearchHit> iterator = searchHits.iterator();
    //6、遍历
    while (iterator.hasNext()) {
        SearchHit searchHit = iterator.next();
        //打印文档对象
        System.out.println(searchHit.getSourceAsString());
        System.out.println("文档的属性");
        Map<String, Object> document = searchHit.getSource();
        System.out.println(document.get("id"));
        System.out.println(document.get("title"));
        System.out.println(document.get("content"));
    }
    client.close();
}

4.1、termQuery

@Testpublic void termQuery() throws Exception{    //1、创建一个QueryBuilder对象    //参数1:要搜索的字段,参数2:要搜索的关键词    QueryBuilder queryBuilder = QueryBuilders.termQuery("title","女护士");    //2、执行查询
    search(queryBuilder);
}

4.2、QueryString

@Testpublic void queryString() throws Exception{    //1、创建一个QueryBuilder对象    //参数1:要搜索的字段,参数2:要搜索的关键词    QueryBuilder queryBuilder = QueryBuilders.queryStringQuery("美丽的女护士").defaultField("title");    search(queryBuilder);
}

4.3、MatchQuery

@Testpublic void matchQuery() throws Exception{    //1、创建一个QueryBuilder对象    //参数1:要搜索的字段,参数2:要搜索的关键词    QueryBuilder queryBuilder = QueryBuilders.matchQuery("title","美丽的女护士");    //2、执行查询
    search(queryBuilder);
}

4.4、查询文档分页操作

@Test public void testQueryMatchAllQuery() throws Exception {    //创建一个QueryBuilder对象    QueryBuilder queryBuilder = QueryBuilders.matchAllQuery();    //执行查询    SearchResponse searchResponse = client.prepareSearch("esstudy")            .setTypes("article")
            .setQuery(queryBuilder)
            .setFrom(0)
            .setSize(5)
            .get();
    //3、取出查询结果
    SearchHits searchHits = searchResponse.getHits();
    //4、取出查询结果的总记录数
    System.out.println("查询结果总记录数:" + searchHits.getTotalHits());
    //5、查询结果列表
    Iterator<SearchHit> iterator = searchHits.iterator();
    //6、遍历
    while (iterator.hasNext()) {
        SearchHit searchHit = iterator.next();
        //打印文档对象
        System.out.println(searchHit.getSourceAsString());
        System.out.println("文档的属性");
        Map<String, Object> document = searchHit.getSource();
        System.out.println(document.get("id"));
        System.out.println(document.get("title"));
        System.out.println(document.get("content"));
    }
    client.close();

}

六、Spring Data ElasticSearch

6.1、Spring Data

Spring Data 是一个用于简化数据库访问,并支持云服务的开源框架。其主要目标是使得对数据的访问变得方便快捷,并支持map-reduce 框架和云计算数据服务。 Spring Data 可以极大的简化 JPA 的写法, 可以在几乎不用写实现的情况下,实现对数据的访问和操作。除了CRUD 外,还包括如分页、排序等一 些常用的功能。

6.2 Spring Data ElasticSearch

Spring Data ElasticSearch 基于 spring data API 简化 elasticSearch 操作,将原始操作 elasticSearch 的

客户端 API 进行封装 。 Spring Data 为 Elasticsearch 项目提供集成搜索引擎。 Spring Data Elasticsearch

POJO 的关键功能区域为中心的模型与 Elastichsearch 交互文档和轻松地编写一个存储库数据访问层。

官方网站: http://projects.spring.io/spring-data-elasticsearch/

6.3、java

pom文件

<dependencies>    <dependency>        <groupId>org.springframework.boot</groupId>        <artifactId>spring-boot-starter-data-elasticsearch</artifactId>    </dependency>    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

application.yml:

spring: data: elasticsearch: cluster-name: my-elasticsearch-----节点名 cluster-nodes: 虚拟机地址:9300

出了自带的CRUD方法外还有

docker整合elk docker elastic_docker整合elk_11

 案例:

实体类:

@Document(indexName ="wlm_ddd" ,type="article")------要创建的索引名和类型public class Article {    @Id    @Field(type = FieldType.Long, store = true)    private long id;    @Field(type = FieldType.Text, store = true, analyzer = "ik_smart")
    private String title;
    @Field(type = FieldType.Text, store = true, analyzer = "ik_smart")
    private String content;

  .........

dao层:

public interface ArticleDao extends ElasticsearchRepository<Article,Long> {  public List<Article> findByTitle(String title);  public List<Article> findByTitleOrContent(String title,String content);    //分页查询 public List<Article> findByTitleOrContent(String title, String content, Pageable pageable);}

测试(自带的crud方法和自己写的方法)

@RunWith(SpringRunner.class)@SpringBootTestpublic class Test {   @Resource   private ArticleDao articleDao;    @Resource
    private ElasticsearchTemplate template;

    @org.junit.Test
    public void createIndex(){
        template.createIndex(Article.class);
    }

    @org.junit.Test
    public void addDocument() throws Exception {
        for (int i = 1; i <= 20; i++) { //创建一个Article对象
            Article article = new Article();
            article.setId(i);
            article.setTitle("女护士路遇昏迷男子跪地抢救:救人是职责更是本能" + i);
            article.setContent("这是一个美丽的女护士妹妹" + i);
            //把文档写入索引库
            articleDao.save(article);
        }
    }

    @org.junit.Test
    public void deleteDocumentById() throws Exception {
        //articleDao.deleteById(2l);
        //全部删除
        articleDao.deleteAll();
        }

        @org.junit.Test
        public void findAll() throws Exception {
            Iterable<Article> articles = articleDao.findAll();
            articles.forEach(a -> System.out.println(a));
        }

        @org.junit.Test
        public void testFindById() throws Exception {
            Optional<Article> optional = articleDao.findById(10l);
            Article article = optional.get();
            System.out.println(article);
        }


        @org.junit.Test
        public void testFindByTitle() throws Exception {
            List<Article> list = articleDao.findByTitle("美丽的护士");
            list.stream().forEach(a -> System.out.println(a));
        }

        @org.junit.Test
        public void testFindByTitleOrContent() throws Exception {

            articleDao.findByTitleOrContent("美丽的女护士", "女护士").forEach(a -> System.out.println(a));
        }

    @org.junit.Test
    public void testFindByTitleOrContent1() throws Exception {
       Pageable pageable =PageRequest.of(1,5);
        articleDao.findByTitleOrContent("美丽的女护士", "女护士",pageable).forEach(a -> System.out.println(a));
    }

    @org.junit.Test
    public void testNativeSearchQuery() throws Exception {
        //创建一个查询对象
        NativeSearchQuery query = new NativeSearchQueryBuilder().withQuery(QueryBuilders.queryStringQuery("女护士").defaultField("title")).withPageable(PageRequest.of(0, 15)).build();
        //执行查询
        List<Article> articleList = template.queryForList(query, Article.class);
        articleList.forEach(a -> System.out.println(a));
    }