一、docker安装Elasticsearch
1、docker pull elasticsearch:指定的版本号(不指定版本号即为最新的)
2、安装es容器
docker run -di --name=**** -p 9200:9200 -p 9300:9300 elasticsearch:5.6.8
name自己自定义,9200端口(Web管理平台端口) 9300(服务默认端口)
输入虚拟机地址访问9200页面:
3、配置:
3.1、登陆容器:docker exec -it 容器名 /bin/bash
3.2、进入config目录:
3.3、 查看文件 :
root@07f22eb41bb5:/usr/share/elasticsearch/config# ls
elasticsearch.yml log4j2.properties scripts
因为没有vi和vim编辑器命令,所有需要安装编辑器
3.3.1、设置 apt 下载源
docker cp ~/sources.list kkb_es:/etc/apt/sources.list
3.3.2、安装vim编辑器
apt-get update
apt-get install vim
3.3.3、修改elasticsearch.yml文件
/etc/security/limits.conf 中的内容
3.3.5、修改/etc/sysctl.conf,追加下面内容
vm.max_map_count=655360
3.3.6、执行sysctl -p,使得内核参数马上生效
这时候Elasticsearch安装成功
二、ElasticSearch的客户端操作
实际开发中,主要有三种方式可以作为 elasticsearch 服务的客户端:
第一种,elasticsearch-head 插件
第二种,使用elasticsearch 提供的 Restful 接口直接访问
第三种,使用elasticsearch 提供的 API 进行访问
2.1、elasticsearch-head
ElasticSearch 不同于 Solr 自带图形化界面,我们可以通过安装 ElasticSearch 的 head 插件,完成图形化界面的效果,完成索引数据的查看。安装插件的方式有两种,在线安装和本地安装。本文档采用本地安 装方式进行head插件的安装。 elasticsearch-5-* 以上版本安装 head 需要安装 node 和 grunt
1 )下载 head 插件: https://github.com/mobz/elasticsearch-head
2 )将 elasticsearch-head-master 压缩包解压到任意目录,但是要和 elasticsearch 的安装目录区别开
3 )下载 nodejs : https://nodejs.org/en/download/
4)将 grunt 安装为全局命令 , Grunt 是基于 Node.js 的项目构建工具
在 cmd控制台中输入如下执行命令:npm install -g grunt-cli
5)进入elasticsearch-head-master目录启动head,在命令提示符下输入命令:
>npm install
>grunt server
这个时候输入localhost:9100 就能打开页面了
如果不能成功连接到es服务,需要修改ElasticSearch的config目录下的配置文件: config/elasticsearch.yml,增加以下两句命令:
http.cors.enabled: true
http.cors.allow-origin: "*"
然后重新启动 ElasticSearch 服务。
三、IK分词器
1、简介
IKAnalyzer 是一个开源的,基于 java 语言开发的轻量级的中文分词工具包。从 2006 年 12 月推出 1.0 版开始,IKAnalyzer 已经推出 了 3 个大版本。最初,它是以开源项目 Lucene 为应用主体的,结合词典分词和文法分析算法的中文分词组件。新版本的IKAnalyzer3.0 则发展为 面向 Java 的公用分词组件,独立于Lucene项目,同时提供了对 Lucene 的默认优化实现。
IK 分词器 3.0 的特性如下:
1 )采用了特有的 “ 正向迭代最细粒度切分算法 “ ,具有 60 万字 / 秒的高速处理能力。
2 )采用了多子处理器分析模式,支持:英文字母(IP 地址、 Email 、 URL )、数字(日期,常用中文数量词,罗马数字,科学计数法),中文词汇(姓名、地名处理)等分词处理。
3 )对中英联合支持不是很好 , 在这方面的处理比较麻烦. 需再做一次查询 , 同时是支持个人词条的优化的词典存储,更小的内存占用。
4 )支持用户词典扩展定义。
5 )针对 Lucene 全文检索优化的查询分析器 IKQueryParser ;采用歧义分析算法优化查询
关键字的搜索排列组合,能极大的提高 Lucene 检索的命中率。
2、安装
(1) 安装 ik 分词器
IK 分词器下载地址 https://github.com/medcl/elasticsearch-analysis-ik/releases
将 ik 分词器上传到服务器上,然后解压,并改名字为 ik
unzip elasticsearch-analysis-ik-5.6.8.zip
mv elasticsearch ik
将 ik 目录拷贝到 docker 容器的 plugins 目录下
docker cp ./ik es容器的名字 : /usr/share/elasticsearch/plugins
(2)测试
ik_max_word :会将文本做最细粒度的拆分
比如会将 “ 中华人民共和国人民大会堂 ” 拆分为 “ 中华人民共和国、中华人民、中华、华人、人民共
和国、人民、共和国、大会堂、大会、会堂等词语。
ik_smart :会做最粗粒度的拆分
比如会将 “ 中华人民共和国人民大会堂 ” 拆分为中华人民共和国、人民大会堂。
四、Kibana
1、下载安装
(1) 镜像下载
docker pull docker.io/kibana : 5.6.8
(2) 安装 kibana 容器
执行如下命令,开始安装 kibana 容器
docker run -it -d -e ELASTICSEARCH_URL = http : //192.168.220.100 : 9200 --name kibana
-p 5601 : 5601 kibana : 5.6.8
ELASTICSEARCH_URL= http://192.168.220.100:9200 :是指链接的 ES 地址
restart=always: 每次服务都会重启,也就是开启启动
5601:5601: 端口号
快捷键
ctrl+i 自动缩进
ctrl+enter 提交请求
down 打开自动补全菜单
enter 或 tab 选中项自动补全
esc 关闭补全菜单
(3) 访问测试
访问 http://虚拟机地址:5601 如下:
2、Kibana使用
1、DSL语句使用
Query DSL 是一个 Java 开源框架用于构建类型安全的 SQL 查询语句。采用 API 代替传统的拼接字符串来构造查询语句。目前Querydsl 支持的平台包括 JPA,JDO , SQL , Java Collections , RDF , Lucene ,Hibernate Search。 elasticsearch 提供了一整套基于 JSON 的 DSL 语言来定义查询
2、索引操作
(1)查询所有索引:GET /_cat/indices?v
(2)删除某个索引 :DELETE /skuinfo
(3) 新增索引 : PUT /user
(4) 创建映射 :
(5)新增文档数据
PUT /user/userinfo/1
{
"name":"李四",
"age":22,
"city":"深圳",
"description":"李四来自湖北武汉!"
}
(6)修改数据 :
PUT /user/userinfo/1
{
"name":"张三丰",
"description":"在武汉读书,家在武汉!在深圳工作!"
}
数据查询:
( 1)查询所有数据 :GET /user/_search
(2)根据ID查询:GET /user/userinfo/2
(3)Sort排序:desc降序,asc 升序
GET /user/_search
{
"query":{
"match_all": {}
},
"sort":{
"age":{
"order":"desc"
}
}
}
(4)分页 :
GET /user/_search
{
"query":{
"match_all": {}
},
"sort":{
"age":{
"order":"desc"
}
},
"from": 0,
"size": 2
}
查询模式:
(1)term 查询(不分词)
term 主要用于分词精确匹配,如字符串、数值、日期等(不适合情况: 1. 列中除英文字符外有其它值 2. 字符串值中有冒号或中文 3. 系统自带属性如 _version )
GET _search
{
"query" :{
"term" :{
"city" : " 武汉 "
}
}
}
(2)terms 查询:
terms 跟 term 有点类似,但 terms 允许指定多个匹配条件。 如果某个字段指定了多个值,那么文档需要一起去做匹配 。
GET _search
{
"query" :{
"terms" :{
"city" :
[
"武汉" ,
"广州"
]
}
}
}
(3)match 查询(分词,广州与武汉都能查到)
GET _search
{
"query": {
"match": {
"city": " 广州武汉 "
}
}
}
(4)范围查询
#过滤-range 范围过滤
#gt表示> gte表示=>
#lt表示< lte表示<=
GET _search
{
"query":{
"range": {
"age": {
"gte": 30,
"lte": 57
}
}
}
}
(5) bool 查询
bool 可以用来合并多个条件查询结果的布尔逻辑,它包含一下操作符:
must : 多个查询条件的完全匹配 , 相当于 and 。
must_not : 多个查询条件的相反匹配,相当于 not 。
should : 至少有一个查询条件匹配 , 相当于 or 。
GET _search
{
"query" : {
"bool" : {
"must" : [ {
"term" : {
"city" : {
"value" : " 深圳 "
}
}
},
{
"range" :{
"age" :{
"gte" : 20 ,
"lte" : 99
} } } ] } }}
五、java代码操作:
pom.xml 坐标
<dependencies> <dependency> <groupId>org.elasticsearch</groupId> <artifactId>elasticsearch</artifactId> <version>5.6.8</version> </dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>transport</artifactId>
<version>5.6.8</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-to-slf4j</artifactId>
<version>2.9.1</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.24</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.21</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.12</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.8.1</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.1</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.8.1</version>
</dependency>
</dependencies>
@Beforepublic void init() throws Exception{ //1、配置setting Settings settings = Settings.builder().put("cluster.name", "my-elasticsearch").build(); //2、产生客户端 client=new PreBuiltTransportClient(settings);
//3、添加节点信息
client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("192.168.110.128"),9300));
}
1、创建索引index :
@Test
//创建索引
public void test1 () throws Exception
{
//创建名称为 blog2 的索引
client . admin (). indices ().
prepareCreate
(
"blog2"
).
get
();
//释放资源
client . close ();
}
2、创建映射mapping
@Testpublic void setMappings()throws Exception {XContentBuilder builder = XContentFactory.jsonBuilder() .startObject() .startObject("article") .startObject("properties")
.startObject("id").field("type", "integer").field("store", "yes")
.endObject()
.startObject("title").field("type", "string").field("store", "yes").field("analyzer", "ik_smart")
.endObject()
.startObject("content").field("type", "string").field("store", "yes").field("analyzer", "ik_smart")
.endObject()
.endObject()
.endObject()
.endObject();}
3、建立文档document
@Testpublic void createDoc() throws Exception { //1、创建客户端,上面方法已经创建完毕 //2、创建一个文档对象 XContentBuilder builder=XContentFactory.jsonBuilder(); builder.startObject()
.field("id",2l)
.field("title","美好生活")
.field("content","好好努力才可以去追求想要的生活").endObject();
//3、将文档对象添加到索引库
client.prepareIndex()
.setIndex("esstudy")
.setType("article")
.setId("2")
.setSource(builder).get();
client.close();
}
4、查询:
共同点的代码:
@Beforepublic void init() throws Exception{ //1、配置setting Settings settings = Settings.builder().put("cluster.name", "my-elasticsearch").build(); //2、产生客户端 client=new PreBuiltTransportClient(settings);
//3、添加节点信息
client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("192.168.110.128"),9300));
}
private void search(QueryBuilder queryBuilder) { //2、执行查询 SearchResponse searchResponse = client.prepareSearch("esstudy") .setTypes("article") .setQuery(queryBuilder) .get();
//3、取出查询结果
SearchHits searchHits = searchResponse.getHits();
//4、取出查询结果的总记录数
System.out.println("查询结果总记录数:" + searchHits.getTotalHits());
//5、查询结果列表
Iterator<SearchHit> iterator = searchHits.iterator();
//6、遍历
while (iterator.hasNext()) {
SearchHit searchHit = iterator.next();
//打印文档对象
System.out.println(searchHit.getSourceAsString());
System.out.println("文档的属性");
Map<String, Object> document = searchHit.getSource();
System.out.println(document.get("id"));
System.out.println(document.get("title"));
System.out.println(document.get("content"));
}
client.close();
}
4.1、termQuery
@Testpublic void termQuery() throws Exception{ //1、创建一个QueryBuilder对象 //参数1:要搜索的字段,参数2:要搜索的关键词 QueryBuilder queryBuilder = QueryBuilders.termQuery("title","女护士"); //2、执行查询
search(queryBuilder);
}
4.2、QueryString
@Testpublic void queryString() throws Exception{ //1、创建一个QueryBuilder对象 //参数1:要搜索的字段,参数2:要搜索的关键词 QueryBuilder queryBuilder = QueryBuilders.queryStringQuery("美丽的女护士").defaultField("title"); search(queryBuilder);
}
4.3、MatchQuery
@Testpublic void matchQuery() throws Exception{ //1、创建一个QueryBuilder对象 //参数1:要搜索的字段,参数2:要搜索的关键词 QueryBuilder queryBuilder = QueryBuilders.matchQuery("title","美丽的女护士"); //2、执行查询
search(queryBuilder);
}
4.4、查询文档分页操作
@Test public void testQueryMatchAllQuery() throws Exception { //创建一个QueryBuilder对象 QueryBuilder queryBuilder = QueryBuilders.matchAllQuery(); //执行查询 SearchResponse searchResponse = client.prepareSearch("esstudy") .setTypes("article")
.setQuery(queryBuilder)
.setFrom(0)
.setSize(5)
.get();
//3、取出查询结果
SearchHits searchHits = searchResponse.getHits();
//4、取出查询结果的总记录数
System.out.println("查询结果总记录数:" + searchHits.getTotalHits());
//5、查询结果列表
Iterator<SearchHit> iterator = searchHits.iterator();
//6、遍历
while (iterator.hasNext()) {
SearchHit searchHit = iterator.next();
//打印文档对象
System.out.println(searchHit.getSourceAsString());
System.out.println("文档的属性");
Map<String, Object> document = searchHit.getSource();
System.out.println(document.get("id"));
System.out.println(document.get("title"));
System.out.println(document.get("content"));
}
client.close();
}
六、Spring Data ElasticSearch
6.1、Spring Data
Spring Data 是一个用于简化数据库访问,并支持云服务的开源框架。其主要目标是使得对数据的访问变得方便快捷,并支持map-reduce 框架和云计算数据服务。 Spring Data 可以极大的简化 JPA 的写法, 可以在几乎不用写实现的情况下,实现对数据的访问和操作。除了CRUD 外,还包括如分页、排序等一 些常用的功能。
6.2 Spring Data ElasticSearch
Spring Data ElasticSearch 基于 spring data API 简化 elasticSearch 操作,将原始操作 elasticSearch 的
客户端 API 进行封装 。 Spring Data 为 Elasticsearch 项目提供集成搜索引擎。 Spring Data Elasticsearch
POJO 的关键功能区域为中心的模型与 Elastichsearch 交互文档和轻松地编写一个存储库数据访问层。
官方网站: http://projects.spring.io/spring-data-elasticsearch/
6.3、java
pom文件
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch</artifactId> </dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
application.yml:
spring: data: elasticsearch: cluster-name: my-elasticsearch-----节点名 cluster-nodes: 虚拟机地址:9300
出了自带的CRUD方法外还有
案例:
实体类:
@Document(indexName ="wlm_ddd" ,type="article")------要创建的索引名和类型public class Article { @Id @Field(type = FieldType.Long, store = true) private long id; @Field(type = FieldType.Text, store = true, analyzer = "ik_smart")
private String title;
@Field(type = FieldType.Text, store = true, analyzer = "ik_smart")
private String content;
.........
dao层:
public interface ArticleDao extends ElasticsearchRepository<Article,Long> { public List<Article> findByTitle(String title); public List<Article> findByTitleOrContent(String title,String content); //分页查询 public List<Article> findByTitleOrContent(String title, String content, Pageable pageable);}
测试(自带的crud方法和自己写的方法)
@RunWith(SpringRunner.class)@SpringBootTestpublic class Test { @Resource private ArticleDao articleDao; @Resource
private ElasticsearchTemplate template;
@org.junit.Test
public void createIndex(){
template.createIndex(Article.class);
}
@org.junit.Test
public void addDocument() throws Exception {
for (int i = 1; i <= 20; i++) { //创建一个Article对象
Article article = new Article();
article.setId(i);
article.setTitle("女护士路遇昏迷男子跪地抢救:救人是职责更是本能" + i);
article.setContent("这是一个美丽的女护士妹妹" + i);
//把文档写入索引库
articleDao.save(article);
}
}
@org.junit.Test
public void deleteDocumentById() throws Exception {
//articleDao.deleteById(2l);
//全部删除
articleDao.deleteAll();
}
@org.junit.Test
public void findAll() throws Exception {
Iterable<Article> articles = articleDao.findAll();
articles.forEach(a -> System.out.println(a));
}
@org.junit.Test
public void testFindById() throws Exception {
Optional<Article> optional = articleDao.findById(10l);
Article article = optional.get();
System.out.println(article);
}
@org.junit.Test
public void testFindByTitle() throws Exception {
List<Article> list = articleDao.findByTitle("美丽的护士");
list.stream().forEach(a -> System.out.println(a));
}
@org.junit.Test
public void testFindByTitleOrContent() throws Exception {
articleDao.findByTitleOrContent("美丽的女护士", "女护士").forEach(a -> System.out.println(a));
}
@org.junit.Test
public void testFindByTitleOrContent1() throws Exception {
Pageable pageable =PageRequest.of(1,5);
articleDao.findByTitleOrContent("美丽的女护士", "女护士",pageable).forEach(a -> System.out.println(a));
}
@org.junit.Test
public void testNativeSearchQuery() throws Exception {
//创建一个查询对象
NativeSearchQuery query = new NativeSearchQueryBuilder().withQuery(QueryBuilders.queryStringQuery("女护士").defaultField("title")).withPageable(PageRequest.of(0, 15)).build();
//执行查询
List<Article> articleList = template.queryForList(query, Article.class);
articleList.forEach(a -> System.out.println(a));
}