1、索引原理
1.1、倒排索引
倒排索引(Inverted Index) 也叫反向索引,有反向索引必有正向索引。通俗来说,正向索引通过key找Value,反向索引是通过value找key。ES底层在检索时底层使用的就是倒排索引
1.2、索引模型
现有索引和映射如下:
{
"products":{
"mappings":{
"properties":{
"description":{
"type":"text"
},
"price":{
"type":"float"
},
"title":{
"type":"keyword"
}
}
}
}
在ES中除了test类型分词,其他都不分词。
2、分词器
2.1、Analysis和Analyzer
Analysis:文本分析是把全文本转换一系列单词的过程,也叫分词(analyzer)。Analysis是通过Analyzer来实现的分词就是将文档通过Analyzer分词一个一个的Term,每个Term都指向包含这个Term的文档。
2.2、Analyzer组成
-
注意:在ES中默认使用标准分词器: StandardAnalyzer特点:中文单字分词单词分词我是中国人this is good man----> analyzer---->我 是 中 国 人 this is good man
-
分析器(analyzer)都有三种构件组成的:character filters,tokenizers,token filters。
-
character filters 字符过滤器
- 在一段文本进行分词之前,先进行预处理,比如说最常见的就是,过滤html标签( hello --> hello) , & --> and (l&you --> l and you)
-
tokenizers 分词器
英文分词可以根据空格将单词分开,中文分词比较复杂,可以采用机器学习算法来分词。 -
token filters
将切分的单词进行加工。大小写转换(例将“Quick"转为小写),去掉停用词(例如停用词像“a”、“and”、“the”等等),加入同义词(例如同义词像"“jump”和“leap”)。
注意:
- 三者顺序:character filters—>Tokenizer—>Token Filter
- 三者个数 character filters(0或者1个)—>Tokenizer—>Token Filter(0或者多个)
2.3、内置分词器
- Standard Analyzer -默认分词器,英文按单词词切分,并小写处理
- Simple Analyzer 安装单词切分,小写处理
- Stop Analyzer :小写处理,停用词过滤
- Whitespace Analyzer :按照空格切分,不转小写
- Keyword Analyzer 不分词,直接将输入当作输出
2.4、内置分词器测试
- 标准分词器
特点:按照单词分词,英文统一转为小写,过滤标点符号,中文单词分词
POST /_analyze
{
"analyzer": "standard",
"text":"我是中国人,this is a good man!"
}
- Simple分词器
- 按照单词分词,英文统一转为小写,去掉符号,中文按照空格
POST /_analyze
{
"analyzer": "simple"
"text":"我是中国人 中国人民 人啊 ,this is a good man!"
}
- Whitespace 分词器
- 中文英语都按照空格分词,英文不会转换成小写,不去掉标点符号
POST /_analyze
{
"analyzer": "whitespace",
"test":"我是中国人 中国人民 人啊 ,this is a good man"
}
2.5、创建索引设置分词
PUT /test
{
"mappings": {
"properties": {
"title":{
"type": "text"
, "analyzer": "standard" //指定分词器
}
}
}
}
PUT /test/_doc/1
{
"title":"我是夏骄傲,this is a good"
}
GET /test/_search
{
"query": {
"term": {
"title": {
"value": "夏"
}
}
}
}
3、中文分词器----IK的安装
3.1、IK分词器
IK分词器的下载地址
注意:ES版本和IK版本对应才可以
先去git上下载zip
然后移动到es安装路径的plugins去解压即可
3.2、IK分词器的使用
ik有两种颗粒度的拆分:
- ik_smart:会做最粗度的拆分
- ik_max_word:会将文本做最细粒度的拆分
POST /_analyze
{
"analyzer": "ik_max_word",
"text": "中华人民共和国国歌"
}
3.3、停用词和扩展词配置
ik支持我们自己定义 扩展词典和停用词典
- 扩展词 :不是关键词,但也希望被es用来当做关键词来进行检索。
- 停用词:有些关键词,但是业务场景不想使用这些关键词被检索到,就可以将这些词放入停用词典
定义扩展词典和停用词典可以修改lK分词器中config目录中IKAnalyzer.cfg.xml这个文件。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>IK Analyzer 扩展配置</comment>
<!--用户可以在这里配置自己的扩展字典 -->
<entry key="ext_dict">ext.dic</entry>
<!--用户可以在这里配置自己的扩展停止词字典-->
<entry key="ext_stopwords">stop.dic</entry>
<!--用户可以在这里配置远程扩展字典 -->
<!-- <entry key="remote_ext_dict">words_location</entry> -->
<!--用户可以在这里配置远程扩展停止词字典-->
<!-- <entry key="remote_ext_stopwords">words_location</entry> -->
</properties>
然后在该文件夹下创建ext.dic stop.dic文件 添加文字就可以了
如:
然后重启就可以了
4、过滤查询 Filter Query
4.1、过滤查询
过滤查询,其实准确来说,ES中的查询操作分为2种:查询(query)和过滤(filter)。查询即是之前提到的query查询,它(查询)默认会计算每个返回文档的得分,然后根据得分排序。而过滤(filter)只会筛选出符合的文档,并不计算得分,而且它可以缓存文档。所以,单从性能考虑,过滤比查询更快。换句话说过滤适合在大范围筛选数据,而查询则适合精确匹配数据。一般应用时,应先使用过滤操作过滤数据,然后使用查询匹配数据
使用
GET /ems/emp/_search
{
"query":{
"bool":{
"must":[
{"match_all":{}}//查询条件
],
"filter":{....} //过滤条件
}
}
- 注意:
- 在执行filter和query时,先执行filter再执行query
- ES会自动缓存经常使用的过滤器,以加快性能。
4.1、类型
常见的过滤类型:term、terms、ranage、exists、ids等filter
term
GET /products/_search
{
"query": {
"bool": {
"must": [
{"term": {
"description": {
"value": "测试"
}
}}
],
"filter": [
{"term": {
"description": "测试用"
}}
]
}
}
}
范围
范围
范围过滤 ranage filter
范围
exists filter
过滤存在指定字段,获取字段不为空的索引记录使用