一、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文件
![](https://i-blog.csdnimg.cn/blog_migrate/98b397ad098ac401a9e2cab98adf4ebe.png)
3.3.4、修改/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
![](https://i-blog.csdnimg.cn/blog_migrate/0e2429ff2eb9cd5aaa934a4ae713b7e9.png)
5)进入elasticsearch-head-master目录启动head,在命令提示符下输入命令:
>npm install
>grunt server
这个时候输入localhost:9100 就能打开页面了
![](https://i-blog.csdnimg.cn/blog_migrate/726fa7da6c0160b4bbb50adeda275497.png)
如果不能成功连接到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
如下:
![](https://i-blog.csdnimg.cn/blog_migrate/f73300d592a2310d6d99ff0a865755f3.png)
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>
@Before public 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
@Test public 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
@Test public 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、查询:
共同点的代码:
@Before public 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
@Test public void termQuery() throws Exception{ //1、创建一个QueryBuilder对象 //参数1:要搜索的字段,参数2:要搜索的关键词 QueryBuilder queryBuilder = QueryBuilders.termQuery("title","女护士"); //2、执行查询 search(queryBuilder); }
4.2、QueryString
@Test public void queryString() throws Exception{ //1、创建一个QueryBuilder对象 //参数1:要搜索的字段,参数2:要搜索的关键词 QueryBuilder queryBuilder = QueryBuilders.queryStringQuery("美丽的女护士").defaultField("title"); search(queryBuilder); }
4.3、MatchQuery
@Test public 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) @SpringBootTest public 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)); }