Elasticsearch 入门
-
- 基于REST风格的API
- 通用:
- 一.索引操作
- 二.数据操作:
- [三.Mapping 操作](#三.Mapping 操作)
-
- 1.概念:
- 2.查看mapping
- 3.ES数据类型
-
- 3.1常见类型
- [3.2 对象关系类型:](#3.2 对象关系类型:)
- [3.3 结构化类型:](#3.3 结构化类型:)
- [3.4 特殊类型:](#3.4 特殊类型:)
- [3.5 array(数组):](#3.5 array(数组):)
- [3.6 新增:](#3.6 新增:)
- 4.两种映射类型
-
- [4.1.field mapping (动态映射或自动映射):](#4.1.field mapping (动态映射或自动映射):)
- [4.2.Expllcit field mapping(静态映射或手工映射或显示映射):](#4.2.Expllcit field mapping(静态映射或手工映射或显示映射):)
- [5 映射参数](#5 映射参数)
- 四.高级搜索
-
- 1.查询上下文
- 2.相关度评分:_score
- 3.元数据:_source
- [4.常规查询-Query String](#4.常规查询-Query String)
- [5.全文检索-Fulltext query](#5.全文检索-Fulltext query)
- [6.精准查询-Term query](#6.精准查询-Term query)
- 7.过滤器-Filter
- [8.组合查询-Bool query](#8.组合查询-Bool query)
- 五.分词器
-
- 1.规范化(normalization):
- 2.过滤器
- 3.分词器(tokenizer):
- [3.中文分词器 ik分词:](#3.中文分词器 ik分词:)
- 4.热更新
基于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
参数: ==?之前是命令,之后是参数,多个参数用&==分隔。
javascript
//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的通配符查询优化日志行和类似的关键字值
-
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
-
带参数:
// 查询 所有有索引的 数据中带有 xiaomi 的数据
GET /product/_search?q=xiaomi
// 查询 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-01
DELETE 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": {
"name": "xiaomi nfc phone"
},// match_all 匹配所有结果的子句 "match_all":{}, // multi_match 查询 fields 中 包含 query 的信息 "multi_match": { "query": "phone huangmenji", "fields": ["name","desc"] }, // match_phrase 短语查询, 指定查询 name 字段包含 xiaomi nfc 的信息 "match_phrase": { "name": "xiaomi nfc" } }
}
6.精准查询-Term query
-
term:匹配和搜索词项完全相等的结果
-
term 和 match_phrase 区别:
term 搜索不会将搜索词分词match_phrase 会将检索关键词分词, match_phrase的分词结果必须在被检索字段的分词中都包含,而且顺序必须相同,而且默认必须都是连续的
-
term 和 keyword 区别
term 是对于搜索词不分词,keyword 是字段类型,是对于source data中的字段值不分词
-
-
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:必须满足子句(查询)必须出现在匹配的文档中,并将有助于得分。
-
filter :过滤器 不计算相关度分数,cache☆子句(查询)必须出现在匹配的文档中。但是不像 must查询的分数将被忽略。Filter子句在filter上下文中执行,这意味着计分被忽略,并且子句被考虑用于缓存。
-
should:可能满足 or子句(查询)应出现在匹配的文档中。
-
must_not :必须不满足 不计算相关度分数 not子句(查询)不得出现在匹配的文档中。子句在过滤器上下文中执行,这意味着计分被忽略,并且子句被视为用于缓存。由于忽略计分,0因此将返回所有文档的分数。
-
minimum_should_match:参数指定should返回的文档必须匹配的子句的数量或百分比。如果bool查询包含至少一个should子句,而没有must或 filter子句,则默认值为1。否则,默认值为0
示例:
GET product/_search
{
"query": {
"bool": {// 必须满足子句(查询)必须出现在匹配的文档中 "must": [{ // must 的条件1 "match": { "name": "xiaomi phone" } },{ // must 的条件2 "match_phrase": { "desc": "shouji zhong" } }], // 过滤器, 不包含下列条件的数据 "filter": [{ // filter 的条件1 "match": { "name": "xiaomi phone" } },{ // filter 的条件2 "match_phrase": { "desc": "shouji zhong" } }] // should 可能满足 or子句(查询) "should": [{ "match_phrase": { "name": "xiaomi nfc" } },{ "range": { "price": { "lte": "500" } } }] // 必须不满足 "must_not": [{ "match": { "name": "xiaomi nfc" } },{ "range": { "price": { "gte": "500" } } }] // 配合 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": {
"my_char_filter": {
// 使用 mapping 过滤器
"type": "mapping",
"mappings": [ "& => and", "| => or"]
},
"html_strip_char_filter": {
// 使用 html_strip 过滤器
"type": "html_strip",
"escaped_tags": [ "a"]
}
},
"filter": {
"my_stopword": {
// 自定义停用词
"type": "stop",
"stopwords": [ "is", "in","the","a", "at","for" ]
}
},
"tokenizer": {
"my_tokenizer": {
// 正则分词器
"type": "pattern",
"pattern": "[ ,.!?]"
}
},
"analyzer": {
"my_analyzer": {
// custom 设置为自定义分词器
"type": "custom",
// 内置或自定义字符过滤器
"char_filter": [ "my_char_filter", "html_strip_char_filter"],
// 内置或自定义token filter 。 使用停用词 与 转小写过滤器
"filter": ["my_stopword", "lowercase"],
// 内置或自定义分词器。
"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驱动版本兼容性