ElasticSearch之个人记录

ElasticSearch

安装包下载地址:https://download.csdn.net/download/qq_42795277/12912005

ElasticSearch安装与启动

安装(解压即可)

window版本的ElasticSearch下载elasticsearch-5.6.8.zip解压即可用

修改配置文件(elasticsearch.yml)

在 elasticsearch配置文件增加以下两句命令

为了允许elasticsearch跨域访问,如果不不安装后面的elasticsearch-head是可以不修改的,直接启动

http.cors.enabled: true
http.cors.allow-origin: "*"

如果启动报错,那么自己手动打一遍

执行elasticsearch.bat启动

发现控制台如图:发现两个端口9200,9300
在这里插入图片描述

注意:端口9200和9300

9200是http协议的RESTful接口,9300是tcp通信接口,集群间和TCPClient都执行该端口

通过浏览器访问ElasticSearch服务器http://localhost:9200看到显示json数据,代表服务启动成功

注意:ElasticSearch是使用java开发的,当前我使用这个版本的es需要jdk版本1.8以上的,所以安装ElasticSearch之前 保证jdk1.8+的,并且正确配置好jdk环境变量,否则ElasticSearch启动失败

安装ES的图形界面化插件

解压(elasticsearch-head-master.zip)

elasticsearch-head-master服务它是有js开发的,它运行的话需要在node.js上才可以运行
所以我们需要安装node.js

安装完成nodeJS后

然后在cmd控制台输入node -v查看版本号,如果查询出版本号说明安装成功

安装grunt

在cmd控制台中输入如下执行命令

npm install -g grunt-cli

然后进入到D:\RuanJianAnZhuang\CDW_WorkSpase\elasticsearch-head-master目录下启动head

输入以下命令

npm install 

grunt server

在这里插入图片描述

然后我们发现这个nodeJS也提供了一个服务,发现它在9100端口

然后我们访问:http://localhost:9100

注意:如果不能成功连接到ElasticSearch,需要修改ElasticSearch的config目录下的配置文件:config/elasticsearch.yml,增加以下两句命令
http.cors.enabled: true
http.cors.allow-origin: "*"

上面我们已经配置好了

ElasticSearch相关概念(术语)

Relational DB ‐> Databases ‐> Tables ‐> Rows ‐> Columns
Elasticsearch ‐> Indices ‐> Types ‐> Documents ‐> Documents

上面就表示给我们一个形象的记忆

数据库类型数据库表的每条数据字段
Relational DBDatabasesTablesRowsColumns
表示mysql表示MySQL数据库表示MySQL数据库表表示MySQL数据库表的每条记录表示MySQL表的字段
ElasticsearchIndicesTypesDocumentsDocuments

mapping:表示类似于数据库表结构

node:表示一台服务器

分片和复制shard&replidas

分片:相当于我们有一个索引库,好比一张饼,我们切成很多块,就切成4片,4片加起来就是一张完整的饼,这张饼就是索引库,分片就是每一片每一块

复制:就相当于是备份,我们每一块每一片吧, 都应该有一个备份节点,就是说如果这个节点挂了,我们还有其他的备份节点可以继续提供服务,就是解决我们快速查询,海量数据存储,解决负载均衡,高可用的问题

ElasticSearch客户端的操作

安装Postman工具

双击它自动安装在了C:\Users\Administrator\AppData\Local\Postman这个路径下了

我们常用的请求有增删改查

增:PUT

删:DELETE

改:POST

查:GET

使用Postman工具进行Restful接口访问

图示:

在这里插入图片描述

请求路径:http://localhost:9200/blog

请求路径:ElasticSearch服务器/索引库的名称

这里我们没有body中写提交的mapping数据,所以我们访问ElasticSearch服务器看到如图示:

在这里插入图片描述

发送一个索引仓库blog1带mapping数据的请求,分析如下

“mappings”:{} 表示在这里边可以设置mappings信息,设置当前索引的的mappings信息

============================================================================

“mappings”:{

​    “article”:{} 表示,article是一个type的名称(是一个表的名称),其中有个type叫article;type可以有多个

}

============================================================================

“mappings”:{

   “article”:{

      “properties”:{} 表示这个article表下有哪些属性,属性就相当于field(字段)的意思

   }

}

============================================================================

“mappings”:{

   “article”:{

      “properties”:{

         “id”:{} 表示属性

         }

      }

}

============================================================================

“mappings”:{

   “article”:{

      “properties”:{

         “xxx”:{

            “type”:“long” , 表示它的类型,表示长整型

            “store”:“true”, 表示它有存储

            “index”:“not_analyzed”, 表示它不索引,默认就是不索引的,写不写都可以

            “analyzer”:“standard” 表示分析器,表示为标准分析器

            }

         }

      }

}

============================================================================

{
	"mappings":{
		"article":{
			"properties":{
				"id":{
					"type":"long",
					"store":true,
					"index":"not_analyzed"
				},
				"title":{
					"type":"text",
					"store":true,
					"index":"analyzed",
					"analyzer":"standard"
				},
				"content":{
					"type":"text",
					"store":true,
					"index":"analyzed",
					"analyzer":"standard"
				}
			}
		}
	}
}

图示:

在这里插入图片描述

ElasticSearch查看alog1索引仓库图示如下

在这里插入图片描述

创建索引仓库后设置mapping数据

我们可以在创建索引仓库时设置mapping数据,当然也可以在先创建索引仓库在设置mapping数据

向索引库中设置mapping数据

设置相当于修改,所以请求方式为POST

访问请求:ElasticSearch服务/索引仓库/type(表名称)/_mappings(加上这个参数表示我们要设置mappings数据)

访问请求:http://localhost:9200/blod/hello/_mappings

在这里插入图片描述

访问ElasticSearchhttp://localhost:9200发现我们使用Postman向索引库blog设置了mapping数据

如图示 :

在这里插入图片描述

json代码:

{
	"hello":{
		"properties":{
			"id":{
				"type":"long",
				"index":"not_analyzed",
				"store":true
			},
			"title":{
				"type":"text",
				"index":"analyzed",
				"store":true,
				"analyzer":"standard"
			},
			"content":{
				"type":"text",
				"index":"analyzed",
				"store":true,
				"analyzer":"standard"
			}
		}
	}
}

删除索引库

在ElasticSearch使用界面操作删除索引库如图:

在这里插入图片描述

使用Postman删除

因为是删除操作,所以请求方式为:DELETE

访问:ElasticSearch服务/要删除的索引仓库

访问:http://localhost:9200/test1

创建文档document

因为我们创建文档属于修改

所以请求方式为:POST

请求访问:ElasticSearch/索引仓库/type/文档的id

注意:这个文档的id是一个真正的文档id,并不是id属性

请求访问:http://localhost:9200/blog/hello/1

Postman发送创建文档请求,图示

在这里插入图片描述

{
	"id":1,
	"title":"ElasticSearch是一个基于Lucene的搜索服务器",
	"content":"它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java 开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到实时 搜索,稳定,可靠,快速,安装使用方便。"
}

在ElasticSearch服务中刚才在Postman发送的文档数据

图示:

在这里插入图片描述

注意:我们在添加文档的时候,这个属性id并不是索引仓库(_id)的id(这个id是ES自动在每个文档中给我们索引仓库创建的的字段,相当于是主键

修改文档document

因为是修改,所以请求方式为:POST

访问请求:ElasticSearch/索引仓库/type/文档id

请求访问:http://localhost:9200/blog/hello/1

Postman图示:

在这里插入图片描述

ElasticSearch服务查看图示

在这里插入图片描述

删除文档document

因为是删除,所以请求方式为DELETE

请求访问:ElasticSearch/索引仓库/type/文档id

请求访问:http://localhost:9200/blog/hello/1

查询文档document根据id查询

因为是查询,所以请求方式为:GET

请求访问:ElasticSearch/索引仓库/type/文档id

请求访问:http://localhost:9200/blog/hello/1

查询文档-根据关键字查询(querystring)

因为我们要提交一个亲球体,就是请求体里写根据哪些关键词查询数据

所以请求方式为:POST

请求访问:ElasticSearch服务/索引仓库/type/_search(追加参数__searh)

请求访问:http://localhost:9200/blog/hello/_search

详细:

{

​    “query”:{} 查询

​ }

===============================================================

{

​ “query”:{

​    “query_string”:{} 根据字符串查询

​    }

​ }

==================================================================

{

​ “query”:{

​    “query_string”:{

​       “default_field”:“title”, 查询的字段

​       “query”:“搜索服务器” 查询条件,它会先自动分词然后查询的关键词

​       }

​    }

​ }

==================================================================

{
	"query":{
		"query_string":{
			"default_field":"title",
			"query":"搜索服务器"
		}
	}
}
注意 :

将搜索内容“搜索服务器”修改为“钢索”,同样也能搜索到文档,所以我们使用以下的term查询优化

因为它会自动分词,然后根据每个关键词去查询,“钢索” 有“ 索”字关键词,所以查询出来了数据

查询文档-term查询

请求方式:POST

请求访问:ElasticSearch服务/索引仓库/type/_search

请求访问:http://localhost:9200/blog/hello/_search

{
	"query":{
		"term":{
			"title":"搜"
		}
	}
}
注意:term,只能根据单个关键词来查询

还可以使用ElasticSearch服务插件查询索引库

图示:

在这里插入图片描述

IK分词器和ElasticSearch集成使用

在进行字符串查询时,我们发现去搜索 ”搜索服务器“和 “钢索”都可以收到数据;(query_string)

而在进行词条(term)查询时,我们搜索 ”搜索“ 却没有搜索到数据;

其实原因是ElasticSearch的标准分词器导致的,当我们创建索引时,字段使用的是标准分词器:

{
   “mappings”:{
      “article”:{
         “properties”:{
            “id”:{
               “type”:“long”,
               “store”:true,
               “index”:“not_analyzed”
               },
            “title”:{
               “type”:“text”,
               “store”:true,
               “index”:“analyzed”,
               “analyzer”:“standard” 我们使用的分析器是标准分词器
               },
            “content”:{
               “type”:“text”,
               “store”:true,
               “index”:“analyzed”,
               “analyzer”:“standard” 我们使用的分析器是标准分词器
               }
         }
      }
   }
}

标准分析器分词效果测试

ElasticSearch服务/_analyze?分析器属性=分析器&pretty=true&text=字符串

http://localhost:9200/_analyze?analyzer=standard&pretty=true&text=我是程序员

拆分结果为:

{
    "tokens": [
        {
            "token": "我",
            "start_offset": 0,
            "end_offset": 1,
            "type": "<IDEOGRAPHIC>",
            "position": 0
        },
        {
            "token": "是",
            "start_offset": 1,
            "end_offset": 2,
            "type": "<IDEOGRAPHIC>",
            "position": 1
        },
        {
            "token": "程",
            "start_offset": 2,
            "end_offset": 3,
            "type": "<IDEOGRAPHIC>",
            "position": 2
        },
        {
            "token": "序",
            "start_offset": 3,
            "end_offset": 4,
            "type": "<IDEOGRAPHIC>",
            "position": 3
        },
        {
            "token": "员",
            "start_offset": 4,
            "end_offset": 5,
            "type": "<IDEOGRAPHIC>",
            "position": 4
        }
    ]
}

但是我想要的结果是: 我,是,程序,程序员

ElasticSearch集成IK分词器

IK分词器的安装

解压elasticsearch-analysis-ik-5.6.8.zip,然后把解压的elasticsearch文件夹拷贝到elasticsearch-5.6.8\plugins下

并且重命名文件为analysis-ik

然后重新启动ElasticSearch服务elasticsearch.bat 即可即可加载IK分词器

看到如图表示安装成功了

在这里插入图片描述

IK分词器的测试

IK提供了两种分词算法ik_smart和ik_max_word

其中ik_smart为最少拆分,ik_max_word为最细粒度划分

测试最小ik的最小拆分ik_smart

例如拆分使用字符串:我是程序员

请求方式为:POST ,因为我要提交查询查询条件字符串 ”我是程序员“

请求访问:http://localhost:9200/_analyze?analyzer=ik_smart&pretty=true&text=我是程序员

拆分结果为:

{
    "tokens": [
        {
            "token": "我",
            "start_offset": 0,
            "end_offset": 1,
            "type": "CN_CHAR",
            "position": 0
        },
        {
            "token": "是",
            "start_offset": 1,
            "end_offset": 2,
            "type": "CN_CHAR",
            "position": 1
        },
        {
            "token": "程序员",
            "start_offset": 2,
            "end_offset": 5,
            "type": "CN_WORD",
            "position": 2
        }
    ]
}

测试ik的最细拆分(ik_max_word)

请求访问:http://localhost:9200/_analyze?analyzer=ik_maxk_word&pretty=true&text=我是程序员

输出结果为:

{
    "tokens": [
        {
            "token": "我",
            "start_offset": 0,
            "end_offset": 1,
            "type": "CN_CHAR",
            "position": 0
        },
        {
            "token": "是",
            "start_offset": 1,
            "end_offset": 2,
            "type": "CN_CHAR",
            "position": 1
        },
        {
            "token": "程序员",
            "start_offset": 2,
            "end_offset": 5,
            "type": "CN_WORD",
            "position": 2
        },
        {
            "token": "程序",
            "start_offset": 2,
            "end_offset": 4,
            "type": "CN_WORD",
            "position": 3
        },
        {
            "token": "员",
            "start_offset": 4,
            "end_offset": 5,
            "type": "CN_CHAR",
            "position": 4
        }
    ]
}

重新新建一个索引库,修改mapping分析器为ik

请求方式为:PUT

请求访问:http://localhost:9200/blog

{
	"mappings":{
		"hello":{
			"properties":{
				"id":{
					"type":"long",
					"store":true,
					"index":"not_analyzed"
				},
				"title":{
					"type":"text",
					"store":true,
					"index":"analyzed",
					"analyzer":"ik_max_word"
				},
				"content":{
					"type":"text",
					"store":true,
					"index":"analyzed",
					"analyzer":"ik_max_word"
				}
			}
		}
	}
}

然后添加文档document

请求方式为:POST

请求访问:http://localhost:9200/blog/hello/1

{
	"id":1,
	"title":"【test】ElasticSearch是一个基于Lucene的搜索服务器",
	"content":"【test】它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java 开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到实时 搜索,稳定,可靠,快速,安装使用方便"
}

再次使用query_stirng测试,看是否已经优化漏洞

请求方式:POST

请求访问:http://localhost:9200/blog/hello/_search

{
	"query":{
		"query_string":{
			"default_field":"title",
			"query":"搜索服务器"
		}
	}
}

使用ik分词后,使用query_string查询比如“钢索”带有“索”字关键词,这样的查询就解决了

就没有查询出来了

测试term,它也可以用ik分词查询了

请求方式:POST

{
	"query":{
		"term":{
			"title":"搜索"
		}
	}
}

因为使用ik进行了分词,本来term就是使用分词关键词查询的

所以ik分词它肯定可以用来查询

ElasticSearch集群

因为我们只有一台服务器,所以我们复制ElasticSearch三个单机服务来模拟多个服务器集群

注意:(删除data目录 )

在我们现在现有的ElasticSearch服务,搭建集群时需要删除data目录

关闭ElasticSearch服务

复制两个elasticsearch-5.6.8,需要重命名为其他名称

修改每台服务器的配置

修改config\elasticsearch.yml配置文件

node1节点服务器

#配置集群
#节点1的配置信息
#集群名称,保证唯一
cluster.name: my-elasticsearch
#节点名称,必须不一样
node.name: node-1
#必须为本机的ip地址
network.host: 127.0.0.1
#服务端口号,在同一机器下必须不一样
http.port: 9200
#集群间通信端口号,在同一机器下必须不一样
transport.tcp.port: 9300
#设置集群自动发现机器ip集合
discovery.zen.ping.unicast.hosts: ["127.0.0.1:9300","127.0.0.1:9301","127.0.0.1:9302"]

node2节点服务器

#配置集群
#节点1的配置信息
#集群名称,保证唯一
cluster.name: my-elasticsearch
#节点名称,必须不一样
node.name: node-2
#必须为本机的ip地址
network.host: 127.0.0.1
#服务端口号,在同一机器下必须不一样
http.port: 9201
#集群间通信端口号,在同一机器下必须不一样
transport.tcp.port: 9301
#设置集群自动发现机器ip集合
discovery.zen.ping.unicast.hosts: ["127.0.0.1:9300","127.0.0.1:9301","127.0.0.1:9302"]

node3节点服务器

#配置集群
#节点1的配置信息
#集群名称,保证唯一
cluster.name: my-elasticsearch
#节点名称,必须不一样
node.name: node-3
#必须为本机的ip地址
network.host: 127.0.0.1
#服务端口号,在同一机器下必须不一样
http.port: 9202
#集群间通信端口号,在同一机器下必须不一样
transport.tcp.port: 9302
#设置集群自动发现机器ip集合
discovery.zen.ping.unicast.hosts: ["127.0.0.1:9300","127.0.0.1:9301","127.0.0.1:9302"]

依次启动node1,2,3的服务器

进入到每个服务器的bin\elasticsearch.bat 双击启动

集群测试

添加索引库设置mappings数据

请求方式:PUT

请求访问: http://localhost:9200/blog

{
	"mappings":{
		"hello":{
			"properties":{
				"id":{
					"type":"long",
					"store":true,
					"index":"not_analyzed"
				},
				"title":{
					"type":"text",
					"store":true,
					"index":"analyzed",
					"analyzer":"ik_max_word"
				},
				"content":{
					"type":"text",
					"store":true,
					"index":"analyzed",
					"analyzer":"ik_max_word"
				}
			}
		}
	}
}
添加文档

请求方式:POST

请求访问: http://localhost:9200/blog/hello/1

{
	"id":1,
	"title":"ElasticSearch是一个基于Lucene的搜索服务器",
	"content":"它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java 开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到实时 搜索,稳定,可靠,快速,安装使用方便。"
}
访问ElasticSearch服务查看集群

请求访问: http://localhost:9100/

因为我们开了集群三个端口服务9200,9201,9201 所以我们随便请求访问那个端口都是可以的

看到如图

每一个分片都有一个复制

在这里插入图片描述

ElasticSearch编程操作

使用java客户端管理ES

测试一般我们都放在es集群上,在自己电脑上练习不用es集群了,太占电脑资源。

所以在config\elasticsearch.yml添加如下配置

cluster.name: my-elasticsearch
network.host: 127.0.0.1

其实不用添加也是可以的,默认的名字就是elastcesearch,ip就是本地

创建一个java工程
添加jar包,添加maven的坐标
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>cn.cdw</groupId>
    <artifactId>es-first</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>
    <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.9.6</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
            <version>2.9.0</version>
        </dependency>
    </dependencies>


</project>
编写测试方法实现创建索引库

创建一个Setting对象,相对于是一个配置信息,主要配置集群名称

创建一个客户端Client对象

使用Client对象创建一个索引库

关闭Client对象

package cn.cdw.es;

import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.transport.client.PreBuiltTransportClient;
import org.junit.Test;

import java.net.InetAddress;

public class ElasticSearchClient {
    /*
     * @author DW-CHEN
     *测试创建索引仓库
     */
    @Test
    public void createIndex() throws Exception{
      //创建一个Setting对象,相当于是一个配置信息。主要配置集群名称
        Settings settings=Settings.builder()
                .put("cluster.name","my-elasticsearch")
                .build();
        //创建一个客户端Client对象
       TransportClient transportClient = new PreBuiltTransportClient(settings);
        transportClient.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"),9300));
        //比如,9301,添加代码如上
        // transportClient.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"),9301));

        //使用client对象创建一个索引库
        transportClient.admin().indices().prepareCreate("idea-test")
                //执行操作
                .get();
        //关闭Client对象
        transportClient.close();
    }
}

运行:

然后访问: http://localhost:9100/

发现我们已经创建了一个idea-test的索引仓库,里面没有mapping数据

使用java客户端设置mappings数据

创建一个Setting对象

创建一个Client对象

创建一个mapping信息,应该是一个json数据,可以是字符串,也可以是XContenxtBuilder对象

使用client向es服务器发送mapping信息

关闭client对象

 @Test
    public void SetMappings() throws  Exception{
        //创建一个Setting对象
        Settings settings = Settings.builder()
                .put("cluster.name","my-elasticsearch")
                .build();
        //Client
        TransportClient transportClient = new PreBuiltTransportClient(settings)
                .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));

        //创建一个mapping信息
        /*
        {
	"hello":{
		"properties":{
			"id":{
				"type":"long",
				"index":"not_analyzed",
				"store":true
			},
			"title":{
				"type":"text",
				"index":"analyzed",
				"store":true,
				"analyzer":"ik_max_word"
			},
			"content":{
				"type":"text",
				"index":"analyzed",
				"store":true,
				"analyzer":"ik_max_word"
			}
		}
	}
}
         */

        //使用XContentBuilder来拼接json格式
        XContentBuilder xContentBuilder= XContentFactory.jsonBuilder()
        //开始拼接json数据
        .startObject()
          .startObject("hello")
            .startObject("properties")
                .startObject("id")
                    .field("type","long")
                    .field("store",true)
                    .field("index","not_analyzed")
                .endObject()
                .startObject("title")
                    .field("type","text")
                    .field("store",true)
                    .field("index","analyzed")
                    .field("analyzer","ik_max_word")
                .endObject()
                .startObject("content")
                    .field("type","text")
                    .field("store",true)
                    .field("index","analyzed")
                    .field("analyzer","ik_max_word")
                .endObject()
             .endObject()
            .endObject()
           .endObject();

        //使用client把mappings数据设置到索引仓库中
        transportClient.admin().indices()
                //设置要做映射的索引
                .preparePutMapping("idea-test")
                //设置要要做映射的type
                .setType("hello")
                //mappings数据
                .setSource(xContentBuilder)
                //执行操作
                .get();
        //关闭client资源
        transportClient.close();

    }

运行

访问:http://localhost:9001发现索引仓库idea-test有了刚才我设置的mapping数据了

使用java客户端添加文档

创建一个setting对象

创建一个client对象

创建一个文档对象,创建一个jons格式的字符串,或者使用XContentBuilder

使用Client对象把文档添加到索引库中

关闭client

@Test
    public void testAddDocument() throws  Exception{
        //创建setting
        Settings settings=Settings.builder()
                .put("cluster.name","my-elasticsearch")
                .build();
        //创建client
        TransportClient transportClient = new PreBuiltTransportClient(settings)
                .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"),9300));

        /*
        拼接文档jons数据

         */
        XContentBuilder xContentBuilder=XContentFactory.jsonBuilder()
                .startObject()
                    .field("id",1)
                    .field("title","ElasticSearch是一个基于Lucene的搜索服务器")
                    .field("content","它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用 Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到 实时搜索,稳定,可靠,快速,安装使用方便。")
                .endObject();

            transportClient.prepareIndex()
                    //设置索引仓库名称
                    .setIndex("idea-test")
                    //设置type
                    .setType("hello")
                    //设置id,如果不设置的话自动的生成id
                    .setId("1")
                    //设置文档信息
                    .setSource(xContentBuilder)
                    //执行操作
                    .get();

            //关闭资源
            transportClient.close();
    }

运行

访问http://localhos:9100

发现idea-test索引仓库已将创建好了文档数据

建立文档(使用Jackson转换实体)

引入jackson坐标

 <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.9.6</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
            <version>2.9.0</version>
        </dependency>

创建type实体

package cn.cdw.es.cn.cdw.pojo;

public class Hello {
    private int id;
    private String title;
    private String content;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }
}

发送文档内容

@Test
    public void testAddDocument2()throws Exception{
        //创建settings
        Settings settings=Settings.builder()
                .put("cluster.name","my-elasticsearch")
                .build();
        //创建client
        TransportClient transportClient=new PreBuiltTransportClient(settings)
                .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"),9300));

                //创建文档实体类,设置文档内容
        Hello hello=new Hello();
        hello.setId(1);
        hello.setTitle("【第二条数据】ElasticSearch是一个基于Lucene的搜索服务器");
        hello.setContent("【第二条数据】它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用 Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到 实时搜索,稳定,可靠,快速,安装使用方便。");

        //将文档实体对象转换为jons格式字符串
        ObjectMapper objectMapper = new ObjectMapper();
        String jsonDocument=objectMapper.writeValueAsString(hello);
        //控制台打看一下json格式
        System.out.println(jsonDocument);

        //使用client对象将文档写入到索引库
        transportClient.prepareIndex("idea-test", "hello", "2")
                .setSource(jsonDocument, XContentType.JSON)
                .get();
        //关闭资源
        transportClient.close();
    }

运行

请求访问:http://localhost:9001 发现也添加了条数据

查询文档操作
使用文档ID查询文档

创建一个settings对象

创建一个client对象,可以使用QueryBuilders工具类创建QueryBulider对象

使用client执行查询

得到查询的结果的总记录数

package cn.cdw.es;

import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.transport.client.PreBuiltTransportClient;
import org.junit.Test;

import java.net.InetAddress;
import java.util.Iterator;
import java.util.Map;

/*
查询文档
 */
public class SearchIndex {
    /*
    根据id查询
     */
    @Test
    public void searchById() throws Exception {
        //创建settings
        Settings settings=Settings.builder()
                .put("cluster.name","my-elasticsearch")
                .build();
        //创建client
        TransportClient transportClient = new PreBuiltTransportClient(settings)
                .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));

        //创建一个查询对象QueryBuilder,根据id查询,指定id,查询id为1和2的文档内容
        QueryBuilder queryBuilder = QueryBuilders.idsQuery().addIds("1", "2");

        //执行查询,
        SearchResponse searchResponse=transportClient.prepareSearch("idea-test") //指定索引仓库
                .setTypes("hello") //指定type
                .setQuery(queryBuilder) //根据id查询
                .get(); //执行查询

        //取出查询结果
        SearchHits searchHits=searchResponse.getHits();
        //查询结果总数
        Long totalHits=searchHits.getTotalHits();
        System.out.println("查询结果总记录数为: "+totalHits);

        //查询结果列表
        Iterator<SearchHit> iterator = searchHits.iterator();
        //遍历获取到的数据
        while (iterator.hasNext()) {
            SearchHit searchhit = iterator.next();
            //打印文档对象,以json格式输出
            System.out.println("查询到的数据为: "+searchhit.getSourceAsString());

            //获取文档的属性
            System.out.println("================获取文档的属性=================");
            Map<String, Object> document = searchhit.getSource();
            //它是一个map集合,我们根据文档字段获取值
            System.out.println("id: " + document.get("id"));
            System.out.println("title:  "+document.get("title"));
            System.out.println("content:  " + document.get("content"));

        }

        //关闭资源
        transportClient.close();
    }
}

运行

关键词查询
 @Test
    public void searchByTerm() throws Exception{
        //创建settings
        Settings settings=Settings.builder()
                .put("cluster.name","my-elasticsearch")
                .build();
        //创建client
        TransportClient transportClient=new PreBuiltTransportClient(settings)
                .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"),9300));

        //创建QueryBuilder,根据term关键词查询,指定要查询的字段和要查询的关键词
        //参数一:要搜索的字段
        //参数二:要搜索的关键词
        QueryBuilder queryBuilder = QueryBuilders.termQuery("title", "搜索");

        //使用client执行查询,指定索引仓库,type
        SearchResponse searchResponse=transportClient.prepareSearch("idea-test") //设置索引库
                //设置type
                .setTypes("hello")
                //设置查询条件
                .setQuery(queryBuilder)
                //执行查询
                .get();

        //获取查询结果
          SearchHits searchHits=searchResponse.getHits();

          //查询结果总记录数
        Long totalcount=searchHits.getTotalHits();
        System.out.println("查询结果总记录数为: "+totalcount);

        //查询结果列表
        Iterator<SearchHit>iterator=searchHits.iterator();
        //遍历列表
        while (iterator.hasNext()) {
            SearchHit document = iterator.next();
            //直接输出json格式的字符串格式
            System.out.println("查询到的数据为: "+document.getSourceAsString());

            //上面是直接把jons格式之间转换为字符串输出,下面我们使用根据属性字段获取值
            System.out.println("======================根据属性字段名获取值=====================");

            Map<String, Object> source = document.getSource();
            System.out.println("id: "+source.get("id"));
            System.out.println("title: "+source.get("title"));
            System.out.println("content: "+source.get("content"));
        }
                //关闭资源
        transportClient.close();
    }
字符串查询
 @Test
    public void searchByQueryString()throws Exception {
        //创建Settings
        Settings settings=Settings.builder()
                .put("cluster.name","my-elasticsearch")
                .build();
        //创建client
        TransportClient transportClient = new PreBuiltTransportClient(settings)
                .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));

        //查询条件,根据QueryString查询
        QueryBuilder queryBuilder = QueryBuilders.queryStringQuery("搜索服务器") //指定查询字符串
                .defaultField("title"); //指定要查询的字段。如果不写,默认查询的就是整个域

        //使用client执行查询
        SearchResponse searchResponse=transportClient.prepareSearch("idea-test")  //设置查询的索引仓库
                //设置查询的type
                .setTypes("hello")
                //设置查询的条件
                .setQuery(queryBuilder)
                //执行操作
                .get();

        //获取查询结果
        SearchHits searchHits = searchResponse.getHits();
        //查询结果总记录个数
        Long searchTotalCount=searchHits.getTotalHits();
        System.out.println("查询到的总记录数为: "+searchTotalCount);

        //获取所有的数据列表
        Iterator<SearchHit> searchHitIterator=searchHits.iterator();
        while (searchHitIterator.hasNext()) {
            SearchHit document = searchHitIterator.next();
            //将json数据转换为字符串在控制台输出
            System.out.println("查询到的数据为: " + document.getSourceAsString());

            //根据自动名称获取值
            System.out.println("==================根据字段名称获取值==================");
            Map<String, Object> source = document.getSource();
            System.out.println("id: " + source.get("id"));
            System.out.println("title: " + source.get("title"));
            System.out.println("content: " + source.get("content"));
        }
        //释放资源
        transportClient.close();
    }
添加多条数据(为后面的分页查询提供时数据)
 @Test
    public void addMoreDocument()throws Exception {
        Settings settings=Settings.builder()
                .put("cluster.name","my-elasticsearch")
                .build();

        TransportClient transportClient = new PreBuiltTransportClient(settings)
                .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));


        ObjectMapper objectMapper = new ObjectMapper();
        //插入100条数据,使用循环
        for (int i = 1; i <= 100; i++) {
            Hello hello=new Hello();
            hello.setId(i);
            hello.setTitle("【第"+i+"条数据的title】: "+" ElasticSearch是一个基于Lucene的搜索服务器");
            hello.setContent("【第"+i+"条数据的content】: "+" 它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用 Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到 实时搜索,稳定,可靠,快速,安装使用方便。");
            //转换为json格式
            String jsonDocument=objectMapper.writeValueAsString(hello);

           //建立文档,指定索引仓库,type,id
            transportClient.prepareIndex("idea-test", "hello", hello.getId().toString())
                    //json的文档数据
                    .setSource(jsonDocument.getBytes(), XContentType.JSON).get();
        }
        //释放资源
        transportClient.close();
    }
分页查询

在client对象中执行查询之前,设置分页信息

分页需要设置两个值:

from:起始行号,从0开始

size:每页显示记录数

  @Test
    public void searchByPage()throws  Exception {
        //Settings
        Settings settings = Settings.builder()
                .put("cluster.name", "my-elasticsearch")
                .build();
        //client
        TransportClient transportClient = new PreBuiltTransportClient(settings)
                .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));

        //查询条件,查询全部
        QueryBuilder queryBuilder=QueryBuilders.matchAllQuery();
        //使用client执行查询
        SearchRequestBuilder searchRequestBuilder=transportClient.prepareSearch("idea-test")  //设置索引仓库
                .setTypes("hello") //设置type
                .setQuery(queryBuilder); //设置查询条件,查询全部

        //设置分页信息,查询起始行号和每页显示多少条数据
        SearchResponse searchResponse=searchRequestBuilder
                .setFrom(0)  //设置起始行号,从0
                .setSize(3)//设置每页显示多少条数据,默认查询出来的是10条数据
                .get();//执行操作

        //获得查询结果
        SearchHits hits = searchResponse.getHits();
        //输出查询到的数据
        System.out.println("查询到的总记录为:" + hits.getTotalHits());

        //获取列表数据
        Iterator<SearchHit> iterator = hits.iterator();
        //遍历
        while (iterator.hasNext()) {
            SearchHit next = iterator.next();
            //将json格式的数据转换为字符串输出
            System.out.println("查询到的数据: " + next.getSourceAsString());

            //根据所字段名获取值
            System.out.println("====================根据字段名获取值=================");
            Map<String, Object> source = next.getSource();
            System.out.println("id: " + source.get("id"));
            System.out.println("title: "+source.get("title"));
            System.out.println("content: " + source.get("content"));
        }
        //关闭资源
        transportClient.close();
    }
查询结果高亮显示操作

ElasticSearch可以对查询出的内容的关键字部分进行标签和样式的设置,但是你需要告诉ElasticSearch使用什么标签对高亮关键字进行包裹

设置高亮显示的步骤

设置高亮显示的前缀

设置高亮显示的后缀

在client对象执行之前,设置高亮显示的信息

@Test
    public void searchByHighlight()throws  Exception {
        //创建Setting
        Settings settings = Settings.builder()
                .put("cluster.name", "my-elasticsearch")
                .build();
        //创建Client
        TransportClient transportClient=new PreBuiltTransportClient(settings)
                .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"),9300));

        //查询条件,根据字符串查询
        QueryBuilder queryBuilder = QueryBuilders.queryStringQuery("搜索服务器")
                .defaultField("title");

        //使用client设置请求信息
        SearchRequestBuilder searchRequestBuilder = transportClient.prepareSearch("idea-test")  //设置索引仓库
                .setTypes("hello") //设置type
                .setQuery(queryBuilder) //设置搜索条件
                .setFrom(0) //设置分页信息的查询起始行
                .setSize(3); //设置分页信息每页显示多少条数据

        //设置高亮数据信息
        HighlightBuilder highlightBuilder=new HighlightBuilder();
        //设置高亮前缀
        highlightBuilder.preTags("<font style='color:red'>");
        //设置高亮后缀
        highlightBuilder.postTags("</font>");
        //设置高亮字段
        highlightBuilder.field("title");
        //然后把高亮信息添加到请求信息中
        searchRequestBuilder.highlighter(highlightBuilder);

        //执行操作
        SearchResponse searchResponse=searchRequestBuilder.get();

        //获取查询数据列表
        SearchHits hits = searchResponse.getHits();
        //查询到的总个数
        System.out.println("查询到的总数是:" + hits.getTotalHits());

        //遍历
        for(SearchHit searchhit:hits){
            //将json格式装换为字符串输出到控制台
            System.out.println("查询到的内容为:" + searchhit.getSourceAsString());
            Map<String, HighlightField> highlightFields = searchhit.getHighlightFields();
            System.out.println("map方式打印的高亮内容: " + highlightFields);

            //遍历map集合,打印分析
            System.out.println("title: " + highlightFields.get("title"));
            System.out.println("获取分段: " + highlightFields.get("title").getFragments());
            //遍历
            System.out.println("=============遍历高亮集合,打印高亮片段========================");
            Text[] text=highlightFields.get("title").getFragments();
            for (Text str : text) {
                System.out.println(str);
            }

        }
        //关闭资源
        transportClient.close();
    }

Spring Data ElasticSearch使用

创建一个实体类,其实就是一个javabean(pojo)映射到一个document文档

​ 需要添加一些注解依赖进行标注

创建一个dao,是一个接口,需要继承ElasticSearchRepository接口

编写测试代码

新建一个maven工程

导入Spring Data ElasticSearch坐标

pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>cn.cdw</groupId>
    <artifactId>springdata-elasticsearch</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>
    <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>


    <dependency>
        <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-elasticsearch</artifactId>
        <version>3.0.5.RELEASE</version>
        <exclusions>
            <exclusion>
                <groupId>org.elasticsearch.plugin</groupId>
                <artifactId>transport-netty4-client</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-test</artifactId>
        <version>5.0.4.RELEASE</version>
    </dependency>

</project>

创建applicationContent.xml配置文件,引入ElasticSearch命名空间

配置包扫描器

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:elasticsearch="http://www.springframework.org/schema/data/elasticsearch"
       xsi:schemaLocation="
		http://www.springframework.org/schema/beans
		http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context
		http://www.springframework.org/schema/context/spring-context.xsd
		http://www.springframework.org/schema/data/elasticsearch
		http://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch-1.0.xsd
		">
    <!--配置包扫描器,扫描dao的接口 自动创建实例-->
    <elasticsearch:repositories base-package="cn.cdw.es.dao"/>
    <!--扫描service包,创建service的实体-->
    <context:component-scan base-package="cn.cdw.es.service"/>


    <!--elastic客户对象的配置-->
    <elasticsearch:transport-client id="esClient" cluster-name="my-elasticsearch"
                                    cluster-nodes="127.0.0.1:9300"/>
    <bean id="elasticsearchTemplate" class="org.springframework.data.elasticsearch.core.ElasticsearchTemplate">
        <constructor-arg name="client" ref="esClient"/>
    </bean>

</beans>

编写实体 映射到一个document文档,需要使用一些注解进行标注

package cn.cdw.es.pojo;

import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;

/*
使用注解@Document标注它是一个文档
 */
//注解@Document 表示文档对象,指定索引仓库和type
@Document(indexName = "idea-index",type="article")
public class Article {
    @Id  //注解@Id表示文档主键 , 唯一标识
    //注解@Field每个文档的字段配置
    @Field(type= FieldType.Long,store=true,index = false)  //配置类型,是否存储,分析器
    private Long id;
    @Field(type=FieldType.text,store=true,index = true,analyzer="ik_max_word",searchAnalyzer = "ik_max_word")
    private String title;
    @Field(type=FieldType.text,store=true,index = true,analyzer = "ik_max_word",searchAnalyzer = "ik_max_word")
    private String Content;

    @Override
    public String toString() {
        return "Article{" +
                "id=" + id +
                ", title='" + title + '\'' +
                ", Content='" + Content + '\'' +
                '}';
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getContent() {
        return Content;
    }

    public void setContent(String content) {
        Content = content;
    }
}

注意:上面的注解解释

@Document(indexName=“xxxx”,type=“xxxx”)
indexName 表示索引仓库的名称(必须填)
type 索引的类型

@Id 主键的唯一标识

@Field(type=FieldType.text,store=true,index=true,analyzer=“ik_max_word”,searchAnalyzer=“ik_max_word”)

type 数据类型

store 是否存储

index 是否设置分词

analyzer 存储时使用的分词

searchAnalyzer 搜索时使用的分词

在dao创建一个dao接口,继承ElasticSearchRepository

ElasticSearchRepository<type,id>,指定它的泛型为索引仓库的type,索引仓库的id

package cn.cdw.es.dao;

import cn.cdw.es.pojo.Article;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;

public interface ArticleDao extends ElasticsearchRepository<Article, Integer> {
    //我们不需要再这个接口里定义什么方法,因为我继承的ElasticSearchRepository里已经定义了一些常用的方法
}

在service中创建一个service接口
package cn.cdw.es.service;

import cn.cdw.es.pojo.Article;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

public interface ArticleService {
    //保存,更新文档
    public void save(Article article);

    //删除文档
    public void delete(Article article);

    //查询所有数据
    public Page<Article> findAllPage(Pageable pageable);
}

service接口的实现类定义
package cn.cdw.es.service.impl;

import cn.cdw.es.dao.ArticleDao;
import cn.cdw.es.pojo.Article;
import cn.cdw.es.service.ArticleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

@Service
public class ArticleServiceImpl implements ArticleService {
    //注入dao
    @Autowired
    private ArticleDao articleDao;

    //保存,更新文档数据
    @Override
    public void save(Article article) {
        //调用dao的方法
        articleDao.save(article);
    }
    //删除文档数据
    @Override
    public void delete(Article article) {
        articleDao.delete(article);

    }
    //分页查询
    @Override
    public Page<Article> findAllPage(Pageable pageable) {
       Page<Article> page = articleDao.findAll(pageable);
        return page;
    }
}

编写测试类

测试保存,更新文档

测试删除文档

测试分页查询文档

package cn.cdw.es.test;

import cn.cdw.es.pojo.Article;
import cn.cdw.es.service.ArticleService;
import org.elasticsearch.client.transport.TransportClient;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import java.util.List;

@RunWith(SpringJUnit4ClassRunner.class) //测试环境
@ContextConfiguration("classpath:applicationContext.xml") //加载配置文件
public class ArticleTest {
    //注入service
    @Autowired
    private ArticleService articleService;
    //注入Client
    @Autowired
    private TransportClient transportClient;
    //注入Template
    @Autowired
    private ElasticsearchTemplate elasticsearchTemplate;

    /*
    创建索引仓库和mapping数据
     */
    @Test
    public void createIndex(){
        //使用ElasticSearchTemplate创建索引仓库和mapping数据
        elasticsearchTemplate.createIndex(Article.class);
        elasticsearchTemplate.putMapping(Article.class);

    }

    /*
    测试添加文档
    和
    测试保存
     */
    @Test
    public void createDocument() {
        //创建Article实体
        Article article=new Article();
        //设置id
        article.setId(102L);
        //设置title
        article.setTitle(" ElasticSearch是一个基于Lucene的搜索服务器");
        //设置content
        article.setContent("它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用 Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到 实时搜索,稳定,可靠,快速,安装使用方便。");

        //调用service方法,执行操作
        articleService.save(article);
    }

    /*
    测试更新数据
     */
    @Test
    public void update() {
        Article article=new Article();
        article.setId(101L);
        article.setTitle("【测试更更新数据】ElasticSearch是一个基于Lucene的搜索服务器");
        article.setContent("【测试更更新数据】它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用 Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到 实时搜索,稳定,可靠,快速,安装使用方便。");
        articleService.save(article);

    }

    /*
    测试删除
     */
    @Test
    public void delete() {
        Article article=new Article();
        article.setId(102L);
        articleService.delete(article);
    }

    /*
    批量添加数据
     */
    @Test
    public void createMordDocument() {
        //使用循环批量添加数据
        for (long i = 1; i < 100; i++) {
            Article article=new Article();
            article.setId(i);
            article.setTitle(i+"ElasticSearch是一个基于Lucene的搜索服务器");
            article.setContent(i+"它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用 Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到 实时搜索,稳定,可靠,快速,安装使用方便。");

            articleService.save(article);
        }


    }

    /*
    分页查询
     */
    @Test
    public void findAllPage() {
        PageRequest pageable = PageRequest.of(0,3);
        Page<Article> allPage = articleService.findAllPage(pageable);
        //查询到的数据的总个数
        System.out.println("查询到的总个数为: "+allPage.getTotalElements());
        //获取文档列表内容
        List<Article> content = allPage.getContent();
        //遍历
        for (Article article : content) {
            System.out.println(article);
        }
    }
}

自定义查询方法查询

如果想自定义查询方法,需要遵守ElasticSearch的查询命名规则

常用查询命名规则
关键字命名规则解释示例
andfindByField1AndField2根据Field1和Field2获取数据findByTitleAndContent
orfindByField1OrField2根据Field1或Field2获取数据findByTitleOrContent
isfindByField根据Field获得数据findByTitle
notfifindByFieldNot根据Field获得补集数据fifindByTitleNot
betweenfindByFieldBetween获得指定范围的数据findByPriceBetween
lessThanEqualfindByFieldLessThan获得小于等于指定值的数据findByPriceLessThan
实现:
在dao接口自定义方法
package cn.cdw.es.dao;

import cn.cdw.es.pojo.Article;
import org.elasticsearch.action.admin.indices.rollover.Condition;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.stereotype.Repository;

import java.util.List;

public interface ArticleDao extends ElasticsearchRepository<Article, Integer> {
    //我们不需要再这个接口里定义什么方法,因为我继承的ElasticSearchRepository里已经定义了一些常用的方法

    /*
    自定义查询

     */
    //根据title查询,不分页,默认显示10条数据
    public List<Article> findByTitle(String condition);

    //根据title查询,分页
    public Page<Article> findByTitle(String condition, Pageable pageable);
}

service接口
package cn.cdw.es.service;

import cn.cdw.es.pojo.Article;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

import java.util.List;

public interface ArticleService {
    //保存,更新文档
    public void save(Article article);

    //删除文档
    public void delete(Article article);

    //查询所有数据
    public Page<Article> findAllPage(Pageable pageable);

    //根据title查询,不分页,默认显示10条数据
    public List<Article> findByTitle(String condition);

    //根据title查询,分页
    public Page<Article> findByTitle(String condition, Pageable pageable);
}

service的实现
package cn.cdw.es.service.impl;

import cn.cdw.es.dao.ArticleDao;
import cn.cdw.es.pojo.Article;
import cn.cdw.es.service.ArticleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class ArticleServiceImpl implements ArticleService {
    //注入dao
    @Autowired
    private ArticleDao articleDao;

    //保存,更新文档数据
    @Override
    public void save(Article article) {
        //调用dao的方法
        articleDao.save(article);
    }
    //删除文档数据
    @Override
    public void delete(Article article) {
        articleDao.delete(article);

    }
    //分页查询
    @Override
    public Page<Article> findAllPage(Pageable pageable) {
       Page<Article> page = articleDao.findAll(pageable);
        return page;
    }

    //根据title查询,不分页,默认显示10条数据
    @Override
    public List<Article> findByTitle(String condition) {
        //调用dao
        List<Article> articleList = articleDao.findByTitle(condition);
        return articleList;
    }
    //根据title查询,分页
    @Override
    public Page<Article> findByTitle(String condition, Pageable pageable) {
        //调用dao
        Page<Article> articleListPage = articleDao.findByTitle(condition, pageable);
        return articleListPage;
    }
}

测试
package cn.cdw.es.test;

import cn.cdw.es.pojo.Article;
import cn.cdw.es.service.ArticleService;
import org.elasticsearch.client.transport.TransportClient;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import java.util.List;

@RunWith(SpringJUnit4ClassRunner.class) //测试环境
@ContextConfiguration("classpath:applicationContext.xml") //加载配置文件
public class ArticleTest {
    //注入service
    @Autowired
    private ArticleService articleService;
    //注入Client
    @Autowired
    private TransportClient transportClient;
    //注入Template
    @Autowired
    private ElasticsearchTemplate elasticsearchTemplate;

    /*
    创建索引仓库和mapping数据
     */
    @Test
    public void createIndex(){
        //使用ElasticSearchTemplate创建索引仓库和mapping数据
        elasticsearchTemplate.createIndex(Article.class);
        elasticsearchTemplate.putMapping(Article.class);

    }

    /*
    测试添加文档
    和
    测试保存
     */
    @Test
    public void createDocument() {
        //创建Article实体
        Article article=new Article();
        //设置id
        article.setId(102L);
        //设置title
        article.setTitle(" ElasticSearch是一个基于Lucene的搜索服务器");
        //设置content
        article.setContent("它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用 Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到 实时搜索,稳定,可靠,快速,安装使用方便。");

        //调用service方法,执行操作
        articleService.save(article);
    }

    /*
    测试更新数据
     */
    @Test
    public void update() {
        Article article=new Article();
        article.setId(101L);
        article.setTitle("【测试更更新数据】ElasticSearch是一个基于Lucene的搜索服务器");
        article.setContent("【测试更更新数据】它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用 Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到 实时搜索,稳定,可靠,快速,安装使用方便。");
        articleService.save(article);

    }

    /*
    测试删除
     */
    @Test
    public void delete() {
        Article article=new Article();
        article.setId(102L);
        articleService.delete(article);
    }

    /*
    批量添加数据
     */
    @Test
    public void createMordDocument() {
        //使用循环批量添加数据
        for (long i = 1; i < 100; i++) {
            Article article=new Article();
            article.setId(i);
            article.setTitle(i+"ElasticSearch是一个基于Lucene的搜索服务器");
            article.setContent(i+"它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用 Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到 实时搜索,稳定,可靠,快速,安装使用方便。");

            articleService.save(article);
        }


    }

    /*
    分页查询
     */
    @Test
    public void findAllPage() {
        PageRequest pageable = PageRequest.of(0,3);
        Page<Article> allPage = articleService.findAllPage(pageable);
        //查询到的数据的总个数
        System.out.println("查询到的总个数为: "+allPage.getTotalElements());
        //获取文档列表内容
        List<Article> content = allPage.getContent();
        //遍历
        for (Article article : content) {
            System.out.println(article);
        }
    }

    /*
    根据title查询,不分页,默认显示10条数据
     */
    @Test
    public void findByTitle() {
        //查询关键词
        String condition = "搜索服务器";
        //调用service
        List<Article>list=articleService.findByTitle(condition);
        //遍历
        for (Article article : list) {
            System.out.println(article);
        }

    }

    /*
    也是根据title查询,分页
     */
    @Test
    public void findByTitlePage() {
        //搜索关键词
        String condition = "服务器";
        //设置分页
        Pageable pageable=PageRequest.of(0, 3);
        //调用service
        Page<Article> articlePage = articleService.findByTitle(condition, pageable);
        //遍历
        for (Article article : articlePage) {
            System.out.println(article);
        }
    }
}

使用ElasticSearch的原生查询对象进行查询

功能强大,可以根据我们的实际情况来查询

@Test
    public void findByNativeQuery() {
        //创建查询queryStringBuilder
        QueryBuilder queryBuilder = QueryBuilders.queryStringQuery("搜索服务器")  //指定搜索关键词
                .defaultField("title");//指定根据title字段查询

        //设置分页信息
        Pageable pageable=PageRequest.of(0, 3);

        //创建NativeQueryBuilder
        SearchQuery searchQuery=new NativeSearchQueryBuilder()
                .withQuery(queryBuilder) //设置查询关键词
                .withPageable(pageable) //设置分页信息
                .build(); //执行操作

        //使用模板对象执行查询
        List<Article> articleList = elasticsearchTemplate.queryForList(searchQuery, Article.class);
        //遍历
        for (Article article : articleList) {
            System.out.println(article);
        }
    }
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值