官方文档
elasticsearch
https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html
spring
https://docs.spring.io/spring-data/elasticsearch/docs/current/reference/html
docker安装es
#查找镜像
[root@localhost ~]# docker search elasticsearch
#下载镜像
[root@localhost ~]# docker pull elasticsearch
Using default tag: latest
Error response from daemon: manifest for elasticsearch:latest not found: manifest unknown: manifest unknown
#https://hub.docker.com/search?type=image
#查找elasticsearch最新版本tags
#下载指定版本镜像
[root@localhost ~]# docker pull elasticsearch:7.14.2
#建立目录 挂载映射配置文件
mkdir -p /home/elasticsearch/config
#建立目录 挂载映射数据
mkdir -p /home/elasticsearch/data
#建立目录 挂载映射插件
mkdir -p /home/elasticsearch/plugins
#编辑配置文件
vim /home/elasticsearch/config/elasticsearch.yml
#添加配置,允许任何ip连接,es默认不开启远程连接
http.host: 0.0.0.0
transport.host: 0.0.0.0
#赋权
chmod -R 777 /home/elasticsearch/
#启动
docker run --name elasticsearch -p 9200:9200 -p 9300:9300 \
-e "discovery.type=single-node" \
-e ES_JAVA_OPTS="-Xms64m -Xmx512m" \
-v /home/elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml \
-v /home/elasticsearch/data:/usr/share/elasticsearch/data \
-v /home/elasticsearch/plugins:/usr/share/elasticsearch/plugins \
-d elasticsearch:7.14.2
#查看日志
[root@localhost home]# docker logs 83a096a93868
#访问验证
http://192.168.229.200:9200/
安装界面工具elasticsearch-head
[root@localhost ~]# docker pull mobz/elasticsearch-head:5
[root@localhost ~]# docker run --name elasticsearch-head -di -p 9100:9100 docker.io/mobz/elasticsearch-head:5
#访问验证
http://192.168.229.200:9100/
#填写es地址进行连接,一般会提示跨域:
vim elasticsearch.yml
#添加配置
http.cors.enabled: true
http.cors.allow-origin: "*"
请求es报错406:
Content-Type header [application/x-www-form-urlencoded] is not supported
需要修改配置
#进入容器
docker exec -it -u root elasticsearch-head /bin/bash
#编辑6886和7573行,将application/x-www-form-urlencoded改为application/json;charset=UTF-8
vim _site/vendor.js +6886
vim _site/vendor.js +7573
#如果没有vim的话安装:
# 先更新我们的包管理工具
apt-get update
# 然后安装我们需要的vim
apt-get install vim
访问:http://192.168.229.200:9100/
安装界面工具kibana
[root@localhost home]# docker pull kibana:7.14.2
docker run --name kibana -e ELASTICSEARCH_HOSTS=http://192.168.229.200:9200 -p 5601:5601 -d kibana:7.14.2
#访问验证
http://192.168.229.200:5601/
使用http请求
也可以直接使用http请求
参考https://blog.csdn.net/machao0_0/article/details/121583106
安装分词器
es自带的有standard默认、simple、whitespace
根据es的版本下载对应的版本的ik
https://github.com/medcl/elasticsearch-analysis-ik/releases
插件目录下创建目录ik,解压下载的zip,得到:
[root@localhost ik]# pwd
/home/elasticsearch/plugins/ik
[root@localhost ik]#
[root@localhost ik]# ls
commons-codec-1.9.jar commons-logging-1.2.jar config elasticsearch-analysis-ik-7.14.2.jar httpclient-4.5.2.jar httpcore-4.4.4.jar plugin-descriptor.properties plugin-security.policy
重启es
测试
GET _analyze
{
"analyzer": "standard",
"text": "In 2020, Java is the best language in the world."
}
中文分词器:ik_smart、ik_max_word
GET _analyze
{
"analyzer": "ik_smart",
"text": "我买了一台计算机"
}
springboot集成es
依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
RestHighLevelClient方式
配置文件
#主要为ip及端口
elasticsearch.ip=192.168.229.200
elasticsearch.port=9200
elasticsearch.pool=10
elasticsearch.cluster.name=elasticsearch
配置类
//8开始不支持TransportClient,需使用RestHighLevelClient
@Bean
public RestHighLevelClient restHighLevelClient(){
return new RestHighLevelClient(RestClient.builder(new HttpHost(hostName,port,"http")));
}
创建实体类备用
public class User {
private Integer id;
private String username;
}
//创建索引
@Test
public void testIndexData() throws IOException {
CreateIndexRequest request = new CreateIndexRequest("es_demo_index1");
CreateIndexResponse createIndexResponse = client.indices().create(request, RequestOptions.DEFAULT);
System.out.println(createIndexResponse.index());
System.out.println(createIndexResponse);
}
//判断索引是否存在
@Test
public void testExistIndex () throws IOException{
GetIndexRequest request = new GetIndexRequest("es_demo_index1");
boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);
System.out.println(exists);
}
//删除索引
@Test
public void deleteIndex() throws IOException {
DeleteIndexRequest request = new DeleteIndexRequest("es_demo_index1");
AcknowledgedResponse delete = client.indices().delete(request, RequestOptions.DEFAULT);
System.out.println("是否删除成功:" + delete.isAcknowledged());
}
//创建文档
@Test
public void createDocument() throws IOException {
User user = new User().setId(2).setUsername("zh");
IndexRequest request = new IndexRequest("user_index");
//设置规则 PUT /user_index/_doc/1
request.id("1");
//超时时间
request.timeout(TimeValue.timeValueSeconds(1));
//数据放入请求中
request.source(JSONObject.toJSONString(user), XContentType.JSON);
IndexResponse index = client.index(request, RequestOptions.DEFAULT);
System.out.println("创建结果:" + index);
}
//获取文档
@Test
public void getDocument() throws IOException {
GetRequest request = new GetRequest("user_index", "1");
boolean exists = client.exists(request, RequestOptions.DEFAULT);
if (!exists) {
return;
}
GetResponse response = client.get(request, RequestOptions.DEFAULT);
System.out.println("文档:" + response);
System.out.println("文档内容:" + response.getSourceAsString());
}
//更新文档
@Test
public void updateDocument() throws IOException {
UpdateRequest request = new UpdateRequest("user_index", "1");
User user = new User().setId(2).setUsername("bob");
request.doc(JSONObject.toJSONString(user), XContentType.JSON);
UpdateResponse update = client.update(request, RequestOptions.DEFAULT);
System.out.println("更新结果:" + update);
}
//删除文档
@Test
public void deleteDocument() throws IOException {
DeleteRequest request = new DeleteRequest("user_index", "1");
DeleteResponse delete = client.delete(request, RequestOptions.DEFAULT);
System.out.println("删除结果:" + delete.status());
}
//批量插入
@Test
public void createBulkDocument() throws IOException {
//构建批量插入的请求
BulkRequest request = new BulkRequest();
request.timeout("10s");
//设置数据
List<User> list = new ArrayList<>();
list.add(new User().setId(1).setUsername("张三"));
list.add(new User().setId(2).setUsername("李四"));
list.add(new User().setId(3).setUsername("王五"));
list.add(new User().setId(4).setUsername("赵六"));
for (int i = 0; i < list.size(); i++) {
request.add(new IndexRequest("user_index")
.id(String.valueOf(i + 1))
.source(JSONObject.toJSONString(list.get(i)), XContentType.JSON));
}
BulkResponse bulk = client.bulk(request, RequestOptions.DEFAULT);
System.out.println("批量插入是否有失败:" + bulk.hasFailures());
}
//查询
@Test
public void query() throws IOException {
SearchRequest request = new SearchRequest("user_index");
SearchSourceBuilder builder = new SearchSourceBuilder();
//精准匹配
TermQueryBuilder termQuery = QueryBuilders.termQuery("username.keyword", "李四");
//全文
MatchAllQueryBuilder matchAllQuery = QueryBuilders.matchAllQuery();
//关键词匹配?
WildcardQueryBuilder wildcardQuery = QueryBuilders.wildcardQuery("username", "张");
builder.query(termQuery);
request.source(builder);
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
SearchHit[] hits = response.getHits().getHits();
System.out.println("共查询到" + hits.length + "条数据");
System.out.println("查询结果:");
for (SearchHit hit : hits) {
System.out.println(hit.getSourceAsString());
}
}
报错this is not a http port
访问的是es的tcp端口9300,需换成http端口9200
elasticsearchRepository方式
更多参考spring文档
https://docs.spring.io/spring-data/elasticsearch/docs/4.1.2/reference/html/#elasticsearch.repositories
实体类备用
/**
* Document定义索引信息
* Id定义_id
* Field定义字段类型等信息
*/
@Data
@Document(indexName = "book")
public class Book {
@Id
@Field(type = FieldType.Text)
private String id;
@Field(analyzer="ik_max_word")
private String title;
@Field
private String author;
@Field(type = FieldType.Double)
private Double price;
@Field(type = FieldType.Date,format = DateFormat.basic_date_time)
private Date createTime;
@Field(type = FieldType.Date,format = DateFormat.basic_date_time)
private Date updateTime;
}
创建repository,并添加两个自定义方法
public interface ESBookRepository extends ElasticsearchRepository<Book, String> {
/**
* 方法名必须遵守SpringData的规范
* 效果等于
* {"query":{"bool":{"must":[{"query_string":{"query":"?","fields":["title"]}},{"query_string":{"query":"?","fields":["author"]}}]}}}
*/
List<Book> findByTitleOrAuthor(String title, String author);
/**
* 匹配部分高亮显示
*/
@Highlight(fields = {
@HighlightField(name = "title"),
@HighlightField(name = "author")
})
@Query("{\"match\":{\"title\":\"?0\"}}")
List<Book> find(String keyword);
}
测试
//插入、修改
@Test
void insert() {
Book book = Book.builder().id("1").author("bob").createTime(new Date()).build();
repository.save(book);
}
//批量插入
@Test
void insertBatch() {
List<Book> list = new ArrayList<>();
list.add(Book.builder().id("2").author("bob").title("bbb").createTime(new Date()).build());
list.add(Book.builder().id("3").author("tom").title("ttt").price(200d).createTime(new Date()).build());
list.add(Book.builder().id("4").author("lauria").title("lll").createTime(new Date()).build());
repository.saveAll(list);
}
//查找
@Test
void find() {
Optional<Book> optionalBook = repository.findById("4");
Book book = optionalBook.orElse(null);
System.out.println(book);
System.out.println("=======================");
// price是Double类型的
Iterable<Book> books = repository.findAll(Sort.by(Sort.Direction.DESC, "price"));
books.forEach(System.out::println);
}
//自定义方法
@Test
void findCustomMethod() {
List<Book> books = repository.findByTitleOrAuthor("bbb", "bob");
books.forEach(System.out::println);
}
理论部分 todo
层次结构对比
mysql | es |
---|---|
数据库 | 索引 |
表 | 类型 |
行 | 文档 |
列 | 属性 |
表结构 | 映射 |
索引 | 反向索引 |
sql | 查询DSL |
select * from table | get http:// |
update table | put http:// |
delete | delete http:// |
其他
注意点:
- 在ES6.0.0及更高的版本中,创建的索引只能包含一个映射类型
否则将提示:
“Rejecting mapping update to [book] as the final mapping would have more than 1 type: [group, groupTwo]”
#1.报错
WARNING: IPv4 forwarding is disabled. Networking will not work
#编辑
vim /etc/sysctl.conf
#添加
net.ipv4.ip_forward=1
#重启
systemctl restart network
#验证
sysctl net.ipv4.ip_forward
部分参考
https://blog.csdn.net/qq_17040587/article/details/120971124
https://blog.csdn.net/csdn_chenhao/article/details/108983272
https://blog.csdn.net/qq_45069833/article/details/108428430
https://blog.csdn.net/u013089490/article/details/84323903