初识elasticsearch-正向索引和倒排索引
什么是文档和词条?
每一条数据就是一个文档
对文档中的内容分词,得到的词语就是词条
elasticsearch就是面对文档存储的,可以是数据库中的一条商品数据,一个订单信息,文档数据会被反序列化为json格式后存储在elasticsearch中。
什么是正向索引?
基于文档id创建索引。查询词条时必须先找到文档,而后判断是否包含词条
什么是倒排索引?
对文档内容分词,对词条创建索引,并记录词条所在文档信息。查询是现根据词条查询到文档id,而后获取到文档。
例子:id= 1 ,title = 华为小米充电器 id = 2,title = 小米手环
生成词条 文档id = 1 词条term= 华为 文档id = 1,2 词条term= 小米
通过词条查询文档id,在查询到文档
索引(Index):
索引(index):相同类型的文档的集合(有种mysql数据库的表(table)的感觉)
映射(mapping):索引中文档的字段约束信息,类似表的结构约束(类似于表的字段类型约束表结构(schema))
文档(Document):就是一条条的数据,类似数据库中的行(Row),文档都是json格式
字段(Filed):就是JSON文档中的字段,类似数据库中的列(Column)
请求语句(DSL):提供的JSON风格的请求语句,用来操作elasticsearch,实现CRUD
区别:mysql擅长事务类型操作,可以确保数据的安全和一致性
elasticsearch擅长数据的搜索、分析、计算
分词器:
1、分词器作用:
创建倒排索引时对文档分词
用户搜索时,对输入的内容分词
2、IK分词器有几种模式:
ik_smart :智能切分,粗粒度
ik_max_word:最细切分,细粒度
3、IK分词器如何扩展词条,如何停用词条
利用config目录的ikAnalyzer.cfg.xml文件添加扩展词典和停用词典
在词典中添加扩展词条或者停用词条
索引常见mapping属性:
type:字段数据类型,常见的简单类型有:
字符串:text(可分词的文本) 、 keyword(精确值,例如国家、品牌等不可拆)
数值:long、integer、short、byte、double、float、
布尔:boolean
日期:date
对象:object
index:是否创建索引,默认为true
analyzer:使用哪种分词器
properties:该字段的子字段
创建索引库:
es中通过Restful请求操作索引库、文档。请求内容用DSL语句来表示。创建索引库和mapping的DSL语法如下:
PUT /example
{
"mappings": {
"properties": {
"class":{
"type":"text",
"analyzer":"ik_smart"
},
"cources":{
"type":"keyword",
"index":"false"
},
"name":{
"properties":{
"firstName": {
"type":"keyword"
}
}
},
//略
}}}
查看、删除索引库:
查看索引库:get /索引库名
删除索引库:delete /索引库名
索引库和mapping一旦创建无法修改,但是可以添加新的字段:
put /索引库名/_mapping
{
"properties": {
"新字段名":{
"type":"integer"
}
}
}
文档操作:
添加文档:
新增文档DSL语法:
POST /索引库名/_doc/文档id
{
"字段1:"值1",
"字段2":{
"子属性1":"值2",
"子属性2":"值3"
},
// ...
}
删除文档的语法:
DELETE /索引库名/_doc/文档id
修改文档
方式一:全量修改,会删除旧文档,添加新文档
PUT /索引库名/_doc/文档id
{
"字段1:"值1",
"字段2":{
"子属性1":"值2",
"子属性2":"值3"
},
// ...
}
方法二:增量修改,修改指定字段值
POST /索引库名._update/文档id
{
"doc": {
"字段名": "新的值",
}
}
RestClient操作索引库:
es提供了各种不同语言的客户端,这些客户端本质就是组装DSL,通过http请求发送给es
创建索引库
private RestHighLevelClient client;
@BeforeEach
void setUp(){
this.client = new RestHighLevelClient(RestClient.builder(
HttpHost.create("http://192.168.0.1:9200")
));
}
@AfterEach
void tearDown() throws IOException {
client.close();
}
@Test
void testCreateHotelIndex() throws IOException {
//1、创建Request对象 (请求路径,索引库名称)
CreateIndexRequest request = new CreateIndexRequest("hotel");
//2、请求参数,MAPPING_TEMPLATE是静态常量字符串,内容是创建索引库的DSL语句
request.source(MAPPING_TEMPLATE,XContentType.JSON);
//3、发起请求
client.indices().create(request,RequstOptions.DEFAULT);
}
删除索引库
@Test
void testDeleteHotelIndex() throws IOException {
//1、创建Request对象 (请求路径,索引库名称)
DeleteIndexRequest request = new CreateIndexRequest("hotel");
GetIndexRequest requestExist = new CreateIndexRequest("hotel");
//删除索引库
client.indices().delete(request,RequstOptions.DEFAULT);
//判断是否存在索引库
boolean exist = client.indices().exists(requestExist ,RequstOptions.DEFAULT);
}
RestCient 操作文档:
添加酒店数据到索引库
@Test
void testIndexDocument() throws IOException {
//1、创建Request对象 (索引库名称,id)
IndexRequest request = new IndexRequest("indexName").id("1");
//准备json文档
request.source("{\"name\":\"Jack\",\"age\":21}".XContentType.JSON);
//3、发送请求
client.index(request,RequestOptions.DEFAULT);
}