elasticserch 是一个开源的分布式搜索引擎,可以用来实现搜索,日志统计,分析,系统监控等功能
elastic stack (ELK)是以elasticsearch为核心的技术栈,包括beats,Logstash,kibana,elasticsearch
Lucene 是Apache的开源搜索引擎类库,提供了搜索引擎的核心API
文档和词条:
*文档:每一条数据就是一个文档
*词条:对文档中的内容分词,得到的词语就是词条
正向索引
*基于文档id创建索引,查询词条时必须找到文档,然后判断是否包含词条
倒排索引
*对文档内容分词,对词条创建索引,并记录词条所在文档的信息。查询时现根据词条查询到文档id,而后获取到文档。
文档:一条数据就是一个文档,es中式json格式
字段:json文档中的字段
索引:同类型文档的集合
映射:索引中文档的约束,比如字段名称,类型
elasticsearch与数据库的关系
数据库负责事务类操作
elasticsearch负责海量数据的搜索,分析,计算
DSL 是elasticsearch提供的JSON风格的请求语句,用来操作elasticsearch,实现CRUD,
实现的是Rest风格接口,任何语言可以发HTTP请求,都可以接收DSL
分词器的作用:
创建倒排索引时对文档分词
用户搜索时,对输入的内容分词
IK分词器有几种模式?
ik_smart :智能切分,粗粒度
ik_max_word: 最细切分,细粒度
Ik分词器如何扩展词条?如何停用词条
利用config目录IkAnalyzer.cfg.xml文件添加扩展词典和停用词典
在词典中添加扩展词和停用词条
重启docker
mapping常见属性有哪些/
type : 数据类型
index : 是否索引,默认true
analyzer : 分词器
properties :子字段
type常见的有哪些/
字符串 :text ,keyword(不需要分)
数字:long,integer ,short,byte,double, float
布尔 :boolean
日期 :date
对象 :object
创建索引库 :PUT /索引库名
查询索引库 :GET /索引库名
删除索引库 : DELETE /索引库名
添加索引库 : PUT /索引库名/_mapping
创建文档 :PSOT /索引库名 /_doc /文档id {json文档}
查询文档 :GET /索引库名 /_doc /文档id
删除文档 :DELETE /索引库名 /_doc /文档id
修改文档 :
全量修改 : PUT /索引库名 /_doc/文档id {json文档}
增量修改:PSOT /索引库名 /_update /文档id {“doc”:{字段}}
官方文档地址:https://www.elastic.co/guide/en/elasticsearch/client/index.html
导包
//要指定版本号,因为springBoot 中指定的版本不一致 <properties> <elasticsearch.version>7.12.1</elasticsearch.version> </properties> <!--elasticsearch :client--> <dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>elasticsearch-rest-high-level-client</artifactId> </dependency>
索引表
package cn.itcast.hotel.constants; public class HotelIndexConstants { public static final String MAPPING_TEMPLATE = "{\n" + " \"mappings\": {\n" + " \"properties\": {\n" + " \"id\": {\n" + " \"type\": \"keyword\"\n" + " },\n" + " \"name\": {\n" + " \"type\": \"text\",\n" + " \"analyzer\": \"ik_max_word\",\n" + " \"copy_to\": \"all\"\n" + " },\n" + " \"address\": {\n" + " \"type\": \"keyword\",\n" + " \"index\": false\n" + " },\n" + " \"price\": {\n" + " \"type\": \"integer\"\n" + " },\n" + " \"score\": {\n" + " \"type\": \"integer\"\n" + " },\n" + " \"brand\": {\n" + " \"type\": \"keyword\",\n" + " \"copy_to\": \"all\"\n" + " },\n" + " \"city\": {\n" + " \"type\": \"keyword\"\n" + " },\n" + " \"starName\": {\n" + " \"type\": \"keyword\"\n" + " },\n" + " \"business\": {\n" + " \"type\": \"keyword\",\n" + " \"copy_to\": \"all\"\n" + " },\n" + " \"pic\": {\n" + " \"type\": \"keyword\",\n" + " \"index\": false\n" + " },\n" + " \"location\": {\n" + " \"type\": \"geo_point\"\n" + " },\n" + " \"all\": {\n" + " \"type\": \"text\",\n" + " \"analyzer\": \"ik_max_word\"\n" + " }\n" + " }\n" + " }\n" + "}"; }
```file PUT /hotel { "mappings": { "properties": { "id": { "type": "keyword" }, "name": { "type": "text", "analyzer": "ik_max_word", "copy_to": "all" }, "address": { "type": "keyword", "index": "false" }, "price": { "type": "integer" }, "score": { "type": "integer" }, "brand": { "type": "keyword", "copy_to": "all" }, "city": { "type": "keyword" }, "starName": { "type": "keyword" }, "business": { "type": "keyword", "copy_to":"all" }, "pic": { "type": "keyword", "index": "false" }, "location": { "type": "geo_point" }, "all": { "type": "text", "analyzer": "ik_max_word" } } } }
Test
package cn.itcast.hotel; import org.apache.http.HttpHost; import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest; import org.elasticsearch.client.RequestOptions; import org.elasticsearch.client.RestClient; import org.elasticsearch.client.RestHighLevelClient; import org.elasticsearch.client.indices.CreateIndexRequest; import org.elasticsearch.client.indices.GetIndexRequest; import org.elasticsearch.common.xcontent.XContentType; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import java.io.IOException; import static cn.itcast.hotel.constants.HotelIndexConstants.MAPPING_TEMPLATE; public class HotelIndexTest { //先要初始化 private RestHighLevelClient client; @BeforeEach void setUp(){ //初始化 this.client = new RestHighLevelClient(RestClient.builder( HttpHost.create("http://192.168.142.130:9200")//指定虚拟机的端口号 )); } @AfterEach void deadDown() throws IOException { this.client.close();//关闭 } @Test void initTest(){ System.out.println(client); } @Test void createIndexTest() throws IOException { //创建索引对象,并指定索引名 CreateIndexRequest request = new CreateIndexRequest("hotel"); //加载创建索引的表 request.source(MAPPING_TEMPLATE, XContentType.JSON); //执行:indices()封装了所有的索引API client.indices().create(request,RequestOptions.DEFAULT); } //删除索引 @Test void deleteIndexTest() throws IOException { DeleteIndexRequest request = new DeleteIndexRequest("hotel"); client.indices().delete(request,RequestOptions.DEFAULT); } //判断索引是否存在 @Test void existIndexTest() throws IOException { GetIndexRequest request = new GetIndexRequest("hotel"); boolean flag = client.indices().exists(request, RequestOptions.DEFAULT); System.out.println(flag ? "存在":"不存在"); } }
test
package cn.itcast.hotel; import cn.itcast.hotel.pojo.Hotel; import cn.itcast.hotel.pojo.HotelDoc; import cn.itcast.hotel.service.IHotelService; import com.alibaba.fastjson.JSON; import org.apache.http.HttpHost; import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest; import org.elasticsearch.action.index.IndexRequest; import org.elasticsearch.client.RequestOptions; import org.elasticsearch.client.RestClient; import org.elasticsearch.client.RestHighLevelClient; import org.elasticsearch.client.indices.CreateIndexRequest; import org.elasticsearch.client.indices.GetIndexRequest; import org.elasticsearch.common.xcontent.XContentType; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import java.io.IOException; import static cn.itcast.hotel.constants.HotelIndexConstants.MAPPING_TEMPLATE; @SpringBootTest public class HotelIndexDocumentTest { @Autowired private IHotelService hotelService; private RestHighLevelClient client; //操作文档 @Test void selectIndexDocument() throws IOException { //查询hotel 对象 Hotel hotel = hotelService.getById(36934L); //对象转换location HotelDoc hotelDoc = new HotelDoc(hotel); //正确的转json:toJSONString String json = JSON.toJSONString(hotelDoc); //创建文档对象 IndexRequest request = new IndexRequest("hotel").id(hotel.getId().toString()); //将对象转化为json //request.source(JSON.toJSON(hotelDoc),XContentType.JSON); request.source(json,XContentType.JSON); //发送 client.index(request,RequestOptions.DEFAULT); } @BeforeEach void setUp(){ //初始化 this.client = new RestHighLevelClient(RestClient.builder( HttpHost.create("http://192.168.142.130:9200") )); } @AfterEach void deadDown() throws IOException { this.client.close();//关闭 } }
pojo
package cn.itcast.hotel.pojo; import lombok.Data; import lombok.NoArgsConstructor; @Data @NoArgsConstructor public class HotelDoc { private Long id; private String name; private String address; private Integer price; private Integer score; private String brand; private String city; private String starName; private String business; private String location; private String pic; public HotelDoc(Hotel hotel) { this.id = hotel.getId(); this.name = hotel.getName(); this.address = hotel.getAddress(); this.price = hotel.getPrice(); this.score = hotel.getScore(); this.brand = hotel.getBrand(); this.city = hotel.getCity(); this.starName = hotel.getStarName(); this.business = hotel.getBusiness(); this.location = hotel.getLatitude() + ", " + hotel.getLongitude(); //这里进行了转换 this.pic = hotel.getPic(); } }
//查询 @Test void getDocumentByIdTest() throws IOException { //创建获取对象:指定索引和id GetRequest request = new GetRequest("hotel", "36934"); //获取响应结果 GetResponse response = client.get(request,RequestOptions.DEFAULT); //得到source:json原数据 String json = response.getSourceAsString(); //将字符串转换成对象 HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class); System.out.println(hotelDoc); } //更新 @Test void updateDocument() throws IOException { //创建对象 UpdateRequest request = new UpdateRequest("hotel", "36934"); //准备请求参数 request.doc( "starName","四钻", "price","1314" ); //发送请求 client.update(request,RequestOptions.DEFAULT); } //删除 @Test void deleteDocument() throws IOException { DeleteRequest request = new DeleteRequest("hotel", "36934"); client.delete(request,RequestOptions.DEFAULT); }
@Test void bulkRequest() throws IOException { //数据库查询 List<Hotel> hotels = hotelService.list(); BulkRequest request = new BulkRequest(); for (Hotel hotel : hotels) { //转换 HotelDoc hotelDoc = new HotelDoc(hotel); //正确的转Json String json = JSON.toJSONString(hotelDoc); //批量添加数据 request.add(new IndexRequest("hotel") .id(hotel.getId().toString()) .source(json, XContentType.JSON)); } //发送 client.bulk(request, RequestOptions.DEFAULT); }