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安装界面工具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/安装分词器
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": "我买了一台计算机"
}
其他
#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_forwardspringboot集成es
依赖
org.springframework.boot spring-boot-starter-data-elasticsearch
配置文件
#主要为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 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端口9200elasticsearchRepository
更多参考spring文档
https://docs.spring.io/spring-data/elasticsearch/docs/4.1.2/reference/html/#elasticsearch.repositories
实体类备用
@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{ List findByTitleOrAuthor(String title, String author); @Highlight(fields = { @HighlightField(name = "title"), @HighlightField(name = "author") }) @Query("{"match":{"title":"?0"}}") List 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 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 optionalBook = repository.findById("4");
Book book = optionalBook.orElse(null);
System.out.println(book);
System.out.println("=======================");
// price是Double类型的
Iterable books = repository.findAll(Sort.by(Sort.Direction.DESC, "price"));
books.forEach(System.out::println);
}
//自定义方法
@Test
void findCustomMethod() {
List 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:// |
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



