1.分词产生倒排索引表 3.正常查询,根据'华为'查询,直接去倒排索引表检索出来,然后去原数据表中查找出来。 3.倒排索引进行分组,根据'华为'、'荣耀'、'手机'分组。 a.'华为'检索、 b.'荣耀'检索、 c.'手机'检索 d.结果统计 问题: 如果检索条件越多,则查询越慢,重复IO检索倒排索引表
原数据
| doc_id | name | desc | 匹配数(在分词表中出现) |
|---|---|---|---|
| 1 | 华为手机 | 中国第一品牌 | 2 |
| 2 | 华为荣耀手机 | 年轻人用的手机 | 3 |
| 3 | 荣耀手机 | ..... | 2 |
| 4 | 青春版手机 | ..... | 1 |
| 5 | P40手机 | ..... | 1 |
倒排索引表:根据value找key(doc_id)
| 分词 | doc_ids |
|---|---|
| 华为 | [1,2] |
| 手机 | [1,2,3,4,5] |
| 荣耀 | [2,3] |
| 青春版 | [4] |
| P40 | [5] |
正排索引
1.英文: doc values,专用于聚合 2.聚合步骤 a.每篇文档创建的时候生成正排索引,既将文档的单词拆出来 b.第二部将所有文档的相同单词进行聚合 c.当client查询,直接从正排索引表中检索出来
正排索引:根据key找value,先根据原文档生成
| doc_id | value |
|---|---|
| 1 | 华为 |
| 1 | 手机 |
| 2 | 华为 |
| 2 | 荣耀 |
| 2 | 手机 |
| 3 | 荣耀 |
| 3 | 手机 |
| 4 | 青春版 |
| 4 | 手机 |
| 5 | P40 |
| 5 | 手机 |
正排索引表
| count | bucket |
|---|---|
| 2 | 华为 |
| 5 | 手机 |
| 2 | 荣耀 |
| 1 | 青春版 |
| 1 | P40 |
倒排索引和正排索引的区别
1.正排索引是通过文档找单词,既key找value 2.倒排索引是通过单词找文档,既value找key 3.倒排索引和正排索引均是创建index的时候创建,保存在lucene文件中(既磁盘文件) "city" : { "type" : "text", #分词,默认生成倒排索引 "fields" : { "raw" : { "type" : "keyword" # 不分词,系统默认创建,默认生成正排索引 } } } 4正排索引使用非jvm内存,既系统内存 5.聚合的时候使用正排索引 6.没有创建正排索引的字段做聚合查询, 该字段需要将fielddata设置为true
正排索引和fielddata
1.当没有正排索引的字段需要聚合时,需要打开fielddata,然后临时在内存中建立正排索引,fielddata的构建和管理发生在jvm heap中 2.fielddata默认是不开启的,因为text字段比较长,一般只做关键字分词和搜索,很少拿它来进行全文匹配、聚合、排序 3.ES采用了熔断机制避免字段数据一次性超过物理内存大小而导致内存溢出,如果触发熔断,查询会被终止并返回异常 4.fielddata使用的是jvm内存,正排索引的内存不足时会静静的呆在磁盘中,当内存充足时,会进入到内存中提升性能