安装包下载地址:https://download.csdn.net/download/qq_42795277/12912005
window版本的ElasticSearch下载elasticsearch-5.6.8.zip解压即可用
在 elasticsearch配置文件增加以下两句命令
为了允许elasticsearch跨域访问,如果不不安装后面的elasticsearch-head是可以不修改的,直接启动
http.cors.enabled: true http.cors.allow-origin: "*"如果启动报错,那么自己手动打一遍
发现控制台如图:发现两个端口9200,9300
9200是http协议的RESTful接口,9300是tcp通信接口,集群间和TCPClient都执行该端口
通过浏览器访问ElasticSearch服务器http://localhost:9200看到显示json数据,代表服务启动成功
注意:ElasticSearch是使用java开发的,当前我使用这个版本的es需要jdk版本1.8以上的,所以安装ElasticSearch之前 保证jdk1.8+的,并且正确配置好jdk环境变量,否则ElasticSearch启动失败
elasticsearch-head-master服务它是有js开发的,它运行的话需要在node.js上才可以运行 所以我们需要安装node.js
然后在cmd控制台输入node -v查看版本号,如果查询出版本号说明安装成功
在cmd控制台中输入如下执行命令
npm install -g grunt-cli然后进入到D:\RuanJianAnZhuang\CDW_WorkSpase\elasticsearch-head-master目录下启动head
输入以下命令
npm install grunt server然后我们发现这个nodeJS也提供了一个服务,发现它在9100端口
然后我们访问:http://localhost:9100
上面我们已经配置好了
上面就表示给我们一个形象的记忆
数据库类型数据库表表的每条数据字段Relational DBDatabasesTablesRowsColumns表示mysql表示MySQL数据库表示MySQL数据库表表示MySQL数据库表的每条记录表示MySQL表的字段ElasticsearchIndicesTypesDocumentsDocumentsmapping:表示类似于数据库表结构
node:表示一台服务器
分片和复制shard&replidas
分片:相当于我们有一个索引库,好比一张饼,我们切成很多块,就切成4片,4片加起来就是一张完整的饼,这张饼就是索引库,分片就是每一片每一块
复制:就相当于是备份,我们每一块每一片吧, 都应该有一个备份节点,就是说如果这个节点挂了,我们还有其他的备份节点可以继续提供服务,就是解决我们快速查询,海量数据存储,解决负载均衡,高可用的问题
双击它自动安装在了C:\Users\Administrator\AppData\Local\Postman这个路径下了
我们常用的请求有增删改查
增:PUT
删:DELETE
改:POST
查:GET
图示:
请求路径: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数据
设置相当于修改,所以请求方式为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" } } } }因为是删除操作,所以请求方式为:DELETE
访问:ElasticSearch服务/要删除的索引仓库
访问:http://localhost:9200/test1
因为我们创建文档属于修改
所以请求方式为: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自动在每个文档中给我们索引仓库创建的的字段,相当于是主键
因为是修改,所以请求方式为:POST
访问请求:ElasticSearch/索引仓库/type/文档id
请求访问:http://localhost:9200/blog/hello/1
Postman图示:
ElasticSearch服务查看图示
因为是删除,所以请求方式为DELETE
请求访问:ElasticSearch/索引仓库/type/文档id
请求访问:http://localhost:9200/blog/hello/1
因为是查询,所以请求方式为:GET
请求访问:ElasticSearch/索引仓库/type/文档id
请求访问:http://localhost:9200/blog/hello/1
因为我们要提交一个亲球体,就是请求体里写根据哪些关键词查询数据
所以请求方式为: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查询优化
因为它会自动分词,然后根据每个关键词去查询,“钢索” 有“ 索”字关键词,所以查询出来了数据
请求方式:POST
请求访问:ElasticSearch服务/索引仓库/type/_search
请求访问:http://localhost:9200/blog/hello/_search
{ "query":{ "term":{ "title":"搜" } } }还可以使用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-analysis-ik-5.6.8.zip,然后把解压的elasticsearch文件夹拷贝到elasticsearch-5.6.8\plugins下
并且重命名文件为analysis-ik
然后重新启动ElasticSearch服务elasticsearch.bat 即可即可加载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 } ] }请求方式为: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":"【test】ElasticSearch是一个基于Lucene的搜索服务器", "content":"【test】它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java 开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到实时 搜索,稳定,可靠,快速,安装使用方便" }请求方式:POST
请求访问:http://localhost:9200/blog/hello/_search
{ "query":{ "query_string":{ "default_field":"title", "query":"搜索服务器" } } }使用ik分词后,使用query_string查询比如“钢索”带有“索”字关键词,这样的查询就解决了
就没有查询出来了
请求方式:POST
{ "query":{ "term":{ "title":"搜索" } } }因为使用ik进行了分词,本来term就是使用分词关键词查询的
所以ik分词它肯定可以用来查询
因为我们只有一台服务器,所以我们复制ElasticSearch三个单机服务来模拟多个服务器集群
在我们现在现有的ElasticSearch服务,搭建集群时需要删除data目录
修改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"]进入到每个服务器的bin\elasticsearch.bat 双击启动
请求方式: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许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到实时 搜索,稳定,可靠,快速,安装使用方便。" }请求访问: http://localhost:9100/
因为我们开了集群三个端口服务9200,9201,9201 所以我们随便请求访问那个端口都是可以的
看到如图
每一个分片都有一个复制
测试一般我们都放在es集群上,在自己电脑上练习不用es集群了,太占电脑资源。
所以在config\elasticsearch.yml添加如下配置
cluster.name: my-elasticsearch network.host: 127.0.0.1其实不用添加也是可以的,默认的名字就是elastcesearch,ip就是本地
创建一个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数据
创建一个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数据了
创建一个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坐标
<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 发现也添加了条数据
创建一个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(); } }运行
在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(); }创建一个实体类,其实就是一个javabean(pojo)映射到一个document文档
需要添加一些注解依赖进行标注
创建一个dao,是一个接口,需要继承ElasticSearchRepository接口
编写测试代码
配置包扫描器
<?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(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 搜索时使用的分词
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里已经定义了一些常用的方法 }测试保存,更新文档
测试删除文档
测试分页查询文档
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的查询命名规则
功能强大,可以根据我们的实际情况来查询
@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); } }