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 DB | Databases | Tables | Rows | Columns |
表示mysql | 表示MySQL数据库 | 表示MySQL数据库表 | 表示MySQL数据库表的每条记录 | 表示MySQL表的字段 |
Elasticsearch | Indices | Types | Documents | Documents |
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的查询命名规则
常用查询命名规则
关键字 | 命名规则 | 解释 | 示例 |
---|---|---|---|
and | findByField1AndField2 | 根据Field1和Field2获取数据 | findByTitleAndContent |
or | findByField1OrField2 | 根据Field1或Field2获取数据 | findByTitleOrContent |
is | findByField | 根据Field获得数据 | findByTitle |
not | fifindByFieldNot | 根据Field获得补集数据 | fifindByTitleNot |
between | findByFieldBetween | 获得指定范围的数据 | findByPriceBetween |
lessThanEqual | findByFieldLessThan | 获得小于等于指定值的数据 | 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);
}
}