Elasticsearch 入门
- 基于REST风格的API
- 通用:
- 官方文档
- 安装参考
- 一.索引操作
- 1.创建索引:
- 2.查询索引信息:
- 3.删除索引:
- 二.数据操作:
- 1.查询数据:
- 1.1.查询数据:
- 1.2.查询指定文档id:
- 2.更新数据
- 3.添加 & 替换全部数据
- 4.删除数据
- 三.Mapping 操作
- 1.概念:
- 2.查看mapping
- 3.ES数据类型
- 3.1常见类型
- 3.2 对象关系类型:
- 3.3 结构化类型:
- 3.4 特殊类型:
- 3.5 array(数组):
- 3.6 新增:
- 4.两种映射类型
- 4.1.field mapping (动态映射或自动映射):
- 4.2.Expllcit field mapping(静态映射或手工映射或显示映射):
- 5 映射参数
- 四.高级搜索
- 1.查询上下文
- 2.相关度评分:_score
- 3.元数据:_source
- 4.常规查询-Query String
- 5.全文检索-Fulltext query
- 6.精准查询-Term query
- 7.过滤器-Filter
- 8.组合查询-Bool query
- 五.分词器
- 1.规范化(normalization):
- 2.过滤器
- 示例
- 3.分词器(tokenizer):
- 1.默认分词器:standard
- 3.中文分词器 ik分词:
- 4.热更新
- 6.语法含义
基于REST风格的API
通用:
官方文档
安装参考
?pretty 是一个可选参数,如果加上,Elasticsearch 将返回格式化过的 JSON。
请求:
PUT /my_index?pretty
输出示例:
{"acknowledged" : true,"shards_acknowledged" : true,"index" : "my_index"
}
_analyze 查询指定语句的分词结果
GET _analyze
{"analyzer": "standard","text": "xiaomi nfc phone"
}
一.索引操作
1.创建索引:
请求:
PUT /my_index?pretty
输出示例:
{"acknowledged" : true,"shards_acknowledged" : true,"index" : "my_index"
}
响应:
这个输出表示索引已成功创建。
“acknowledged”: true 表示请求已被接受,
“shards_acknowledged”: true 表示所有的分片都已经准备就绪,
“index”: “my_index” 是你刚才创建的索引名称。
2.查询索引信息:
请求:
GET _cat/indices?v
输出示例:
health status index uuid pri rep docs.count docs.deleted store.size pri.store.size
green open .kibana_task_manager_1 C9SW_Y7cQ8-TJQGArKRcDA 1 0 2 0 31.8kb 31.8kb
yellow open my_index 7V75Rtf1QBCslQvWWPOS2A 1 1 0 0 283b 283b
green open .apm-agent-configuration en6N1awvRZSLySqh0yjleA 1 0 0 0 283b 283b
green open .kibana_1 9-gHntOQTCeM8RqViBAaog 1 0 8 1 19.1kb 19.1kb
参数: ==?之前是命令,之后是参数,多个参数用&==分隔。
//v 显示更加详细的信息
GET /_cat/master?v//help 显示命令结果字段说明
GET /_cat/master?help//h 显示命令结果想要展示的字段
GET /_cat/master?h=ip,node
GET /_cat/master?h=i*,node//format 显示命令结果展示格式,支持格式类型:text json smile yaml cbor
GET /_cat/indices?format=json&pretty//s 显示命令结果按照指定字段排序
GET _cat/indices?v&s=index:desc,docs.count:desc
响应:
health:索引的健康状态。它可以是"green"(一切正常),“yellow”(至少所有主分片都是可用的,但不是所有副本分片都可用)或者"red"(有主分片无法使用)。
status:索引的状态。通常情况下,可能的值是"open"或"close"。
index:索引的名称。
uuid:代表索引的唯一标识符。
pri:主分片的数量。
rep:每个主分片的副本数。
docs.count:存储在索引中的文档数量。
docs.deleted:已删除但尚未完全从存储中移除的文档数量。
store.size:索引当前占用的总物理存储空间。
pri.store.size:主分片占用的物理存储空间。
3.删除索引:
请求:
DELETE /my_index?pretty
输出示例:
{"acknowledged" : true
}
响应:
“acknowledged”: true 表示请求已被接受,
注意:该操作是不可逆的,一旦删除,所有存储在索引中的数据都将被永久移除,因此在执行此操作时务必谨慎
二.数据操作:
1.查询数据:
1.1.查询数据:
请求:
GET /my_index/_search
{"query": {"match": {"field_name": "my_value"}}
}
输出示例:
{"took": 30,"timed_out": false,"_shards": {"total": 5,"successful": 5,"skipped": 0,"failed": 0},"hits": {"total": {"value": 1,"relation": "eq"},"max_score": 1.0,"hits": [{"_index": "my_index","_type": "_doc","_id": "1","_score": 1.0,"_source": {"field_name": "my_value"}}]}
}
请求:
在此示例中,我们在名为 my_index 的索引上进行搜索,查找字段 field_name 中值为 my_value 的文档。
响应:
Elasticsearch返回的响应包括一系列关于查询的信息,例如查询所花费的时间、是否超时、命中的文档数等。同时,返回的结果也会包括所有匹配的文档。
1.2.查询指定文档id:
请求:
GET /my_index/_doc/doc_id
输出示例:
{"_index": "my_index","_type": "_doc","_id": "1","_version": 3,"_seq_no": 2,"_primary_term": 2,"found": true,"_source": {"field1": "123","field2": "456"}
}
响应:
_index:文档所在的索引。
_type:文档的类型。在 7.x 版本中,这通常是 _doc。
_id:文档的 ID。
_version: 文档的版本号。每当文档更新时,此数字都会增加。
_seq_no:序列号,每次对文档进行操作时此数字会增加。
_primary_term: 主要期限数,主要用于处理并发控制。
found:如果找到了文档,则此值为 true;否则,为 false。
_source: 文档的原始内容。
如果没有找到与给定 ID 匹配的文档,Elasticsearch 会返回一个状态码为 404 的响应,并且 found 字段的值将为 false。
2.更新数据
1) 全量替换
2) 指定字段更新
请求:
POST /index/_update/1
{"doc": {"name": "小明"}
}
3.添加 & 替换全部数据
请求:
添加示例:
PUT /my_index/_doc/1
{"name": "小刚","name2": "小李"
}替换全部示例:
PUT /my_index/_doc/1
{
"name": "小明"
}
注意:PUT既可以用于插入,也可以用于更新,所以PUT的更新是全量更新,而不是部分更新。也就是上面的语句执行之后,文档会被直接替换,只会有name字段,字段值为小明
4.删除数据
请求:
DELETE /my_index/_doc/1
三.Mapping 操作
1.概念:
ES中的mapping有点类似与RDB中“表结构”的概念,
在MySQL中,表结构里包含了字段名称,字段的类型还有索引信息等。
在Mapping里也包含了一些属性,比如字段名称、类型、字段使用的分词器、是否评分、是否创建索引等属性,并且在ES中一个字段可以有对个类型。
2.查看mapping
GET /my_index/_mappings
3.ES数据类型
3.1常见类型
-
数字类型:
long integer short byte double float half_float scaled_float unsigned_long -
Keywords:
keyword:不分词,适用于索引结构化的字段, 可以用于过滤、排序、聚合。keyword类型的字段只能通过精确值(exact value)搜索到。Id应该用keyword
constant_keyword:始终包含相同值的关键字字段
wildcard:可针对类似grep的通配符查询优化日志行和类似的关键字值
关键字字段通常用于排序, 汇总和Term查询,例如term
。 -
Dates(时间类型):
包括date
和date_nanos
-
alias:
为现有字段定义别名。 -
binary(二进制):binary
-
range(区间类型):
integer_range、float_range、long_range、double_range、date_range -
text:
当一个字段是要被全文搜索的,比如Email内容、产品描述,这些字段应该使用text类型。设置text类型以后,字段内容会被分析,在生成倒排索 引以前,字符串会被分析器分成一个一个词项。text类型的字段不用于排序,很少用于聚合。(解释一下为啥不会为text创建正排索引:大量堆空间,尤其是 在加载高基数text字段时。字段数据一旦加载到堆中,就在该段的生命周期内保持在那里。同样,加载字段数据是一个昂贵的过程,可能导致用户遇到延迟问 题。这就是默认情况下禁用字段数据的原因)
3.2 对象关系类型:
-
object:用于单个JSON对象
-
nested:用于JSON对象数组
-
flattened :允许将整个JSON对象索引为单个字段。
3.3 结构化类型:
-
geo-point:纬度/经度积分
-
geo-shape:用于多边形等复杂形状
-
point:笛卡尔坐标点
-
shape:笛卡尔任意几何图形
3.4 特殊类型:
-
IP地址:ip 用于IPv4和IPv6地址
-
completion:提供自动完成建议
-
tocken_count:计算字符串中令牌的数量
-
murmur3:在索引时计算值的哈希并将其存储在索引中
-
annotated-text:索引包含特殊标记的文本(通常用于标识命名实体)
-
percolator:接受来自query-dsl的查询
-
join:为同一索引内的文档定义父/子关系
-
rank features:记录数字功能以提高查询时的点击率。
-
dense vector:记录浮点值的密集向量。
-
sparse vector:记录浮点值的稀疏向量。
-
search-as-you-type:针对查询优化的文本字段,以实现按需输入的完成
-
histogram:histogram 用于百分位数聚合的预聚合数值。
-
constant keyword:keyword当所有文档都具有相同值时的情况的 专业化。
3.5 array(数组):
在Elasticsearch中,数组不需要专用的字段数据类型。默认情况下,任何字段都可以包含零个或多个值,但是,数组中的所有值都必须具有 相同的数据类型。
3.6 新增:
-
date_nanos:date plus 纳秒
-
features:
4.两种映射类型
4.1.field mapping (动态映射或自动映射):
名称 | 字段 |
---|---|
整数 | long |
浮点数 | float |
true / false | boolean |
日期 | date |
数组 | 取决于数组中的第一个有效值 |
对象 | object |
字符串 | 如果不是数字和日期类型,那会被映射为text和keyword两个类型 |
除了上述字段类型之外,其他类型都必须显示映射,也就是必须手工指定,因为其他类型ES无法自动识别。
4.2.Expllcit field mapping(静态映射或手工映射或显示映射):
PUT /product
{"mappings": {"properties": {"field": {"mapping_parameter": "parameter_value"}}}
}
5 映射参数
-
index:是否对创建对当前字段创建倒排索引,默认true,如果不创建索引,该字段不会通过索引被搜索到,但是仍然会在source元数据中展示
-
analyzer:指定分析器(character filter、tokenizer、Token filters)。
-
boost:对当前字段相关度的评分权重,默认1
-
coerce:是否允许强制类型转换 true “1”=> 1 false “1”=< 1
-
copy_to:该参数允许将多个字段的值复制到组字段中,然后可以将其作为单个字段进行查询
-
doc_values:为了提升排序和聚合效率,默认true,如果确定不需要对字段进行排序或聚合,也不需要通过脚本访问字段值,则可以禁用doc值以节省磁盘 空间(不支持text和annotated_text)
-
dynamic:控制是否可以动态添加新字段
- true 新检测到的字段将添加到映射中。(默认)
- false 新检测到的字段将被忽略。这些字段将不会被索引,因此将无法搜索,但仍会出现在_source返回的匹配项中。这些字段不会添加到映射中,必须显式 添加新字段。
- strict 如果检测到新字段,则会引发异常并拒绝文档。必须将新字段显式添加到映射中
-
eager_global_ordinals:用于聚合的字段上,优化聚合性能。
- Frozen indices(冻结索引):有些索引使用率很高,会被保存在内存中,有些使用率特别低,宁愿在使用的时候重新创建,在使用完毕后丢弃数据,Frozen indices的数据命中频率小,不适用于高搜索负载,数据不会被保存在内存中,堆空间占用比普通索引少得多,Frozen indices是只读的,请求可能是秒级或者分钟级。*eager_global_ordinals不适用于Frozen indices*
-
enable:是否创建倒排索引,可以对字段操作,也可以对索引操作,如果不创建索引,让然可以检索并在_source元数据中展示,谨慎使用,该状态无法修改。
PUT my_index
{
“mappings”: {
“enabled”: false
}
} -
fielddata:查询时内存数据结构,在首次用当前字段聚合、排序或者在脚本中使用时,需要字段为fielddata数据结构,并且创建倒排索引保存到堆中
-
fields:给field创建多字段,用于不同目的(全文检索或者聚合分析排序)
-
format:格式化
“date”: {
“type”: “date”,
“format”: “yyyy-MM-dd”
} -
ignore_above:超过长度将被忽略
-
ignore_malformed:忽略类型错误
-
index_options:控制将哪些信息添加到反向索引中以进行搜索和突出显示。仅用于text字段
-
Index_phrases:提升exact_value查询速度,但是要消耗更多磁盘空间
-
Index_prefixes:前缀搜索
- min_chars:前缀最小长度,>0,默认2(包含)
- max_chars:前缀最大长度,<20,默认5(包含)
-
meta:附加元数据
-
normalizer:
-
norms:是否禁用评分(在filter和聚合字段上应该禁用)。
-
null_value:为null值设置默认值
-
position_increment_gap:
-
proterties:除了mapping还可用于object的属性设置
-
search_analyzer:设置单独的查询时分析器:
-
similarity:为字段设置相关度算法,支持BM25、claassic(TF-IDF)、boolean
26. store:设置字段是否仅查询
- term_vector:运维参数
四.高级搜索
Query DSL(Domain Specific Language)
1.查询上下文
使用query关键字进行检索,倾向于相关度搜索,故需要计算评分。搜索是Elasticsearch最关键和重要的部分。
2.相关度评分:_score
概念:相关度评分用于对搜索结果排序,评分越高则认为其结果和搜索的预期值相关度越高,即越符合搜索预期值。在7.x之前相关度评分默认使用TF/IDF算法计算而来,7.x之后默认为BM25。在核心知识篇不必关心相关评分的具体原理,只需知晓其概念即可。
排序:相关度评分为搜索结果的排序依据,默认情况下评分越高,则结果越靠前。
3.元数据:_source
-
禁用_source:
总结:如果只是为了节省磁盘,可以压缩索引比禁用_source更好。1. 好处:节省存储开销2. 坏处:- 不支持update、update_by_query和reindex API。- 不支持高亮。- 不支持reindex、更改mapping分析器和版本升级。- 通过查看索引时使用的原始文档来调试查询或聚合的功能。- 将来有可能自动修复索引损坏。
-
数据源过滤器:
Including:结果中返回哪些field
Excluding:结果中不要返回哪些field,不返回的field不代表不能通过该字段进行检索,因为元数据不存在不代表索引不存在-
在mapping中定义过滤:支持通配符,但是这种方式不推荐,因为mapping不可变
PUT product {"mappings": {"_source": {"includes": ["name","price"],"excludes": ["desc","tags"]}} }
-
_source 常用过滤规则
// 不查询数据信息 "_source": "false",// 查询obj 对象中的所有属性 "_source": "obj.*", // 查询obj 对象中的 name 属性 "_source": "obj.name", // 查询 obj1,与obj2 对象中的所有属性 "_source": [ "obj1.\*", "obj2.\*" ],// 查询 obj1,与obj2 对象中的所有属性 但是排除 description 属性 "_source": {"includes": [ "obj1.\*", "obj2.\*" ],"excludes": [ "*.description" ] }
-
4.常规查询-Query String
-
查询所有:
GET /product/_search -
带参数:
// 查询索引为product, 所有字段中带有 xiaomi 的文档
GET /product/_search?q=xiaomi
// 查询索引为product, name 字段中带有 xiaomi 的文档
GET /product/_search?q=name:xiaomi -
分页 & 排序:
GET /product/_search?from=0&size=2&sort=price:asc -
精准匹配 exact value
GET /product/_search?q=date:2021-06-01 -
_all搜索 相当于在所有有索引的字段中检索
GET /product/_search?q=2021-06-01DELETE product # 验证_all搜索 PUT product {"mappings": {"properties": {"desc": {"type": "text", "index": false}}} } # 先初始化数据 POST /product/_update/5 {"doc": {"desc": "erji zhong de kendeji 2021-06-01"} }
5.全文检索-Fulltext query
-
match:匹配包含某个term的子句
-
match_all:匹配所有结果的子句
-
multi_match:多字段条件
-
match_phrase:短语查询, 会将检索关键词分词, 分词结果必须在被检索字段的分词中都包含,而且顺序必须相同,而且默认必须都是连续的
示例:
GET index/_search
{"query": {// match 查询包含 name 中的信息"match": {// xiaomi phone 两个是或的关系"name": "xiaomi phone" },"query": {// match 查询包含 name 中的信息"match": {"name": {// “xiaomi”和“phone”被分成两个单词"query":"xiaomi phone", // 或的关系 "operator": "or" } },// match_all 匹配所有结果的子句"match_all":{},// multi_match 查询 fields 中 包含 query 的信息"multi_match": {"query": "phone huangmenji","fields": ["name","desc"]},// match_phrase 短语查询,不做分词处理, 指定查询 name 字段包含 xiaomi nfc 的信息,“slop”表示偏移的量,即中间允许插入的单词数。"match_phrase": {//如果“xiaomi nfc”短语没有匹配到,"query": "xiaomi nfc", //“xiaomi is nfc”也是可以被匹配到的"slop": 1 }}
}
6.精准查询-Term query
-
term:不分词查询, 匹配和搜索词项完全相等的结果
- term 和 keyword 区别
term 是对于搜索词不分词,
keyword 是字段类型,是对于source data中的字段值不分词
- term 和 keyword 区别
-
terms:匹配和搜索词项列表中任意项匹配的结果
-
range:范围查找
- gt:大于
- lt:小于
- gte:大于等于
- lte:小于等于
示例:
GET index/_search
{"query": {// term 搜索不会将搜索词分词"term": {// es 会对于一些类型自动分词, 导致 term 直接搜索, 匹配不到所查找的内容"name": "xiaomi phone"},"term": {// 是字段类型,是对于source data中的字段值不分词"name.keyword": "xiaomi phone"},"terms": {// 查询包含数组中包含其中一项的进行展示"tags": [ "lowbee", "gongjiaoka" ],"boost": 1.0}"range": {// age 年龄 大于等于 10 小于等于 20"age": {"gte": 10,"lte": 20,"boost": 2.0}}"range": {// date 时间 大于等于 2021-04-15 小于 当前时间 - 1天"date": {// 计算时间 - 8 小时"time_zone": "+08:00", "gte": "2021-04-15","lt": "now-1d/d"}}}
}
7.过滤器-Filter
- filter:query 和 filter 的主要区别在:
filter 是结果导向的而query是过程导向。
query 倾向于“当前文档和查询的语句的相关度”
而filter 倾向于“当前文档和查询的条件是不是相符”。即在查询过程中,query是要对查询的每个结果计算相关性得分的,而filter不会。
另外filter有相应的缓存机制,可以提高查询效率。
GET product/_search
{"query": {"constant_score": {"filter": {"term": {"name": "phone"}},// 固定 相关度评分为1.2"boost": 1.2}}
}
8.组合查询-Bool query
-
bool:可以组合多个查询条件,bool查询也是采用more_matches_is_better的机制,因此满足 must 和 should 子句的文档将会合并起来计算分值
-
must (=):必须满足子句(查询)必须出现在匹配的文档中,并将有助于得分。
-
must_not (!=):必须不满足 不计算相关度分数 not子句(查询)不得出现在匹配的文档中。子句在过滤器上下文中执行,这意味着计分被忽略,并且子句被视为用于缓存。由于忽略计分,0因此将返回所有文档的分数。
-
should (or):可能满足 or子句(查询)应出现在匹配的文档中。
- minimum_should_match:参数指定should返回的文档必须匹配的子句的数量或百分比。如果bool查询包含至少一个should子句,而没有must或 filter子句,则默认值为1。否则,默认值为0
-
filter (not in):过滤器 不计算相关度分数,cache☆子句(查询)必须出现在匹配的文档中。但是不像 must 查询的分数将被忽略。Filter子句在filter上下文中执行,这意味着计分被忽略,并且子句被考虑用于缓存。
示例:
GET product/_search
{"query": {"bool": {// 必须满足子句(查询)必须出现在匹配的文档中"must": [{// must 的条件1"match": {"name": "xiaomi phone"}},{// must 的条件2"match_phrase": {"desc": "shouji zhong"}}],// 必须不满足"must_not": [{"match": {"name": "xiaomi nfc"}},{"range": {"price": {"gte": "500"}}}]// should 可能满足 or子句(查询)"should": [{"match_phrase": {"name": "xiaomi nfc"}},{"range": {"price": {"lte": "500"}}}]// 过滤器, 不包含下列条件的数据"filter": [{// filter 的条件1"match": {"name": "xiaomi phone"}},{// filter 的条件2"match_phrase": {"desc": "shouji zhong"}}]// 配合 should 使用, 返回的文档必须匹配 should 的子句的数量或百分比。"minimum_should_match": 2}}
}
五.分词器
1.规范化(normalization):
文档规范化,提高召回率, 无需设置,配置默认使用
- 停用词
- 时态转换
- 大小写
- 同义词
- 语气词
2.过滤器
字符过滤器(character filter):
分词之前的预处理,过滤无用字符
- html_strip: HTML Strip Character Filter:
- 去除html 标签
- 参数:escaped_tags 需要保留的html标签
- mapping:Mapping Character Filter
- 将指定字符替换成指定字符
- pattern_replace:Pattern Replace Character Filter
- 正则规则替换成指定字符
令牌过滤器(token filter):
比如:has=>have him=>he apples=>apple the/oh/a=>干掉
- 同义词转换
synonym synonyms 中配置同义词信息 ,
synonym_graph synonyms_path 在配置文件中配置同义词信息 - 大小写转换
lowercase 大写转小写
uppercase 小写转大写 - 停用词
stopwords 停用词 - 时态转换
- 语气词处理
示例
html_strip 示例
// 删除过滤器
DELETE my_index
// 创建过滤器
PUT my_index
{"settings": {"analysis": {//先对文本进行预处理,删除或者替换或者增加一些字符"char_filter": {"my_char_filter":{// 过滤器类型 html_strip "type":"html_strip",// 需要保留的html标签 比如 a 标签保留"escaped_tags":["a"]}},"analyzer": {"my_analyzer":{"tokenizer":"keyword","char_filter":["my_char_filter"]}}}}
}// 使用过滤器
GET my_index/_analyze
{"analyzer": "my_analyzer","text": "<p>I'm so <a>happy</a>!</p>"
}// 结果
{"tokens": [{"token": """I'm so <a>happy</a>!""","start_offset": 0,"end_offset": 32,"type": "word","position": 0}]
}
Mapping示例
// 删除过滤器
DELETE my_index
// 创建过滤器
PUT my_index
{"settings": {"analysis": {"char_filter": {"my_char_filter":{// 过滤器类型 html_strip "type":"mapping",// 需要过滤的内容与替换的信息"mappings":["滚 => *","垃 => *","圾 => *"]}},"analyzer": {"my_analyzer":{"tokenizer":"keyword","char_filter":["my_char_filter"]}}}}
}// 使用过滤器
GET my_index/_analyze
{"analyzer": "my_analyzer","text": "你就是个垃圾!滚"
}//结果
{"tokens": [{"token": "你就是个**!*","start_offset": 0,"end_offset": 8,"type": "word","position": 0}]
}
pattern_replace示例
// 删除过滤器
DELETE my_index
// 创建过滤器
PUT my_index
{"settings": {"analysis": {"char_filter": {"my_char_filter":{"type":"pattern_replace","pattern":"(\\d{3})\\d{4}(\\d{4})","replacement":"$1****$2"}},"analyzer": {"my_analyzer":{"tokenizer":"keyword","char_filter":["my_char_filter"]}}}}
}
// 使用过滤器
GET my_index/_analyze
{"analyzer": "my_analyzer","text": "您的手机号是17611001200"
}
// 结果
{"tokens": [{"token": "您的手机号是176****1200","start_offset": 0,"end_offset": 17,"type": "word","position": 0}]
}
同义词转换 示例
// synonym_graph 示例
DELETE test_index
PUT /test_index
{"settings": {"analysis": {"filter": {"my_synonym": {"type": "synonym_graph","synonyms_path": "analysis/synonym.txt"}},"analyzer": {"my_analyzer": {"tokenizer": "ik_max_word","filter": ["my_synonym"]}}}}
}
GET test_index/_analyze
{"analyzer": "my_analyzer","text": ["蒙丢丢,大G,霸道,daG"]
}// synonym 示例
DELETE test_index
PUT /test_index
{"settings": {"analysis": {"filter": {"my_synonym": {"type": "synonym","synonyms": ["赵,钱,孙,李=>吴","周=>王"]}},"analyzer": {"my_analyzer": {"tokenizer": "standard","filter": [ "my_synonym" ]}}}}
}
GET test_index/_analyze
{"analyzer": "my_analyzer","text": ["赵,钱,孙,李","周"]
}
大小写示例
// lowercase 大写转小写
GET test_index/_analyze
{"tokenizer": "standard","filter": ["lowercase"], "text": ["AASD ASDA SDASD ASDASD"]
}// uppercase 小写转大写
GET test_index/_analyze
{"tokenizer": "standard","filter": ["uppercase"], "text": ["asdasd asd asg dsfg gfhjsdf asfdg g"]
}// 根据规则 转大写
GET test_index/_analyze
{"tokenizer": "standard","filter": {"type": "condition","filter": "uppercase","script": { // 将小于5长度的信息转为大写"source": "token.getTerm().length() < 5" }},"text": [ "asdasd asd asg dsfg gfhjsdf asfdg g" ]
}
停用词使用
DELETE test_index
PUT /test_index
{"settings": {"analysis": {"analyzer": {"my_analyzer": {"type": "standard",// _english_ 停用语气词"stopwords": [ "me", "you" ]}}}}
}
GET test_index/_analyze
{"analyzer": "my_analyzer", "text": ["Teacher me and you in the china"]
}
3.分词器(tokenizer):
1.默认分词器:standard
常见分词器:
- standard analyzer:默认分词器,中文支持的不理想,会逐字拆分。
- pattern tokenizer:以正则匹配分隔符,把文本拆分成若干词项。
- simple pattern tokenizer:以正则匹配词项,速度比pattern tokenizer快。
- whitespace analyzer:以空白符分隔 Tim_cookie
自定义分词器(custom analyzer):
- char_filter:内置或自定义字符过滤器 。
- token filter:内置或自定义token filter 。
- tokenizer:内置或自定义分词器。
默认分词器示例
GET test_index/_analyze
{"tokenizer": "standard","text": ["Teacher me and you in the china"]
}
custom 自定义分词器
DELETE custom_analysis
PUT custom_analysis
{"settings": {"analysis": {"char_filter": {//定义char_filter,名称为my_char_filter,使用mapping(替换) 的方式"my_char_filter": {// 使用 mapping 过滤器"type": "mapping","mappings": [ "& => and", "| => or"]},"html_strip_char_filter": {// 使用 html_strip 过滤器"type": "html_strip","escaped_tags": [ "a"]}},"filter": {//定义filter,名称为my_stopword,使用stop(去掉虚词) 的方式"my_stopword": {// 自定义停用词"type": "stop","stopwords": [ "is", "in","the","a", "at","for" ]}},"tokenizer": {// 定义tokenizer,名称为my_tokenizer,使用pattern(正则) 的方式"my_tokenizer": {"type": "pattern","pattern": "[ ,.!?]"}},"analyzer": {//定义自己的analyzer 命名为“my_analyzer”"my_analyzer": {// custom 设置为自定义分词器"type": "custom",// 过滤器: 使用的char_filter,里面的方法emoticons 或自定义字符过滤器 在后文中进行定义"char_filter": ["emoticons", "my_char_filter", "html_strip_char_filter"],// 过滤器: 使用的filter,lowercase为ES自带的filter, my_stopword为自定义token filter,在后文进行定义。 使用停用词 与 转小写过滤器"filter": ["lowercase", "my_stopword"],// 分词器: 使用的tokenizer,里面的方法my_tokenizer 或自定义分词器 在后文中进行定义"tokenizer": "my_tokenizer"}}}}
}GET custom_analysis/_analyze
{"analyzer": "my_analyzer","text": ["What is ,<a>as.df</a> ss<p> in ? &</p> | is ! in the a at for "]
}
3.中文分词器 ik分词:
-
安装和部署
- ik下载地址:https://github.com/medcl/elasticsearch-analysis-ik
- Github加速器:https://github.com/fhefh2015/Fast-GitHub
- 创建插件文件夹 cd your-es-root/plugins/ && mkdir ik
- 将插件解压缩到文件夹 your-es-root/plugins/ik
- 重新启动es
-
IK文件描述
- IK分词配置文件: IKAnalyzer.cfg.xml
- 主词库:main.dic
- 英文停用词:stopword.dic,不会建立在倒排索引中
- 特殊词库:
- quantifier.dic:特殊词库:计量单位等
- suffix.dic:特殊词库:行政单位
- surname.dic:特殊词库:百家姓
- preposition:特殊词库:语气词
- 自定义词库:网络词汇、流行词、自造词等
-
ik提供的两种 analyzer:
ik_max_word: 会将文本做最细粒度的拆分,比如会将“中华人民共和国国歌”拆分为“中华人民共和国,中华人民,中华,华人,人民共和国,人民,人,民,共和国,共和,和,国国,国歌”,会穷尽各种可能的组合,适合 Term Query;
ik_smart: 会做最粗粒度的拆分,比如会将“中华人民共和国国歌”拆分为“中华人民共和国,国歌”,适合 Phrase 查询。
IK分词器示例
GET test_index/_analyze
{"tokenizer": "ik_max_word","text": ["我爱北京天安门","天安门上太阳升"]
}
4.热更新
- 远程词库文件
优点:上手简单
缺点:- 词库的管理不方便,要操作直接操作磁盘文件,检索页很麻烦
- 文件的读写没有专门的优化性能不好
- 多一层接口调用和网络传输
- ik访问数据库
MySQL驱动版本兼容性- https://dev.mysql.com/doc/connector-j/8.0/en/connector-j-versions.html
- https://dev.mysql.com/doc/connector-j/5.1/en/connector-j-versions.html
- 驱动下载地址
https://mvnrepository.com/artifact/mysql/mysql-connector-java
6.语法含义
// remove 加入 lowercase后,The 被当成 stopword 删除
GET _analyze
{//先对文本进行预处理,删除或者替换或者增加一些字符"char_filter": [ {"type" : "mapping","mappings" : [ "- => _"]}],//使用whitespace 进行切割"tokenizer": "whitespace", //先转小写,再移除a an the等词 "filter": ["lowercase","stop","snowball"], "text": ["The gilrs in China are playing this game!"]
}