ElasticSearch之个人记录

    科技2022-08-11  102

    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获取数据findByTitleAndContentorfindByField1OrField2根据Field1或Field2获取数据findByTitleOrContentisfindByField根据Field获得数据findByTitlenotfifindByFieldNot根据Field获得补集数据fifindByTitleNotbetweenfindByFieldBetween获得指定范围的数据findByPriceBetweenlessThanEqualfindByFieldLessThan获得小于等于指定值的数据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); } }
    Processed: 0.017, SQL: 8