elasticsearch常用操作
一、批量操作
批量操作文档,通过POST请求发送192.168.56.66:9200/test/_doc/_bulk?pretty 以下调用在一个批量操作中为两个文档(ID 1和ID 2)建立了索引:
/customer/_doc/_bulk?pretty
{"index":{"_id":"1"}}
{"name": "John Doe" }
{"index":{"_id":"2"}}
{"name": "Jane Doe" }在一个批量操作中更新第一个文档(ID为1),然后删除第二个文档(ID为2):
{"update":{"_id":"1"}}
{"doc": { "name": "John Doe becomes Jane Doe" } }
{"delete":{"_id":"2"}}批量导入数据,从服务器本地导入文件数据
请求:name为当前执行路径下的文件,如果不在则改为绝对路径
·
--data-binary @name二、term查询
term查询即单词级别查询,这些查询通常⽤于结构化的数据,⽐如:number, date, keyword等,⽽不是对text。也就是说,全⽂本查询之前要先对⽂本内容进⾏分词, ⽽单词级别的查询直接在相应字段的反向索引中精确查找,单词级别的查询⼀般⽤于数值、⽇期等类型的字段上
查询统一请求入口:
POST es/_search- term query 精准匹配查询
精确匹配字段jerseyNo为23的数据
POST es/_search
{
"query": {
"term": {
"jerseyNo": "23"
}
}
}Exsit Query 在特定的字段中查找⾮空值的⽂档
POST es/_search { "query": { "exists": { "field": "jerseyNo" } } }Prefix Query 查找包含带有指定前缀term的⽂档。类似于mysql的like param%
POST es/_search { "query": { "prefix": { "jerseyNo": "12" } } }Wildcard Query ⽀持通配符查询,*表示任意字符,?表示任意单个字符
POST es/_search { "query": { "wildcard": { "jerseyNo": "1*3" } } }Regexp Query 正则表达式查询
POST es/_search { "query": { "regexp": { "jerseyNo": "1.*2" } } }Ids Query id查询器
POST es/_search { "query": { "ids": { "values": [ 1, 2 ] } } }
三、范围查询
查找指定字段在指定范围内包含值(⽇期、数字或字符串)的⽂档
查询统一请求入口:
POST es/_search查找年龄在2-10岁的人
POST es/_search { "query": { "range": { "age": { "gte": 2, "lte": 10 } } } }查找2001-2010年出生的人
POST es/_search { "query": { "range": { "birthDay": { "gte": "01/01/2001", "lte": "2010", "format": "dd/MM/yyyy||yyyy" } } } }
四、布尔查询
| type | description |
| -------- | ------------------------------------------- |
| must | 必须出现在匹配文档中 |
| filter | 必须出现在匹配文档中,但是结果不打分。score |
| must_not | 不能出现在文档中 |
| should | 应该出现在文档中 |
must 查找名称含有李字的人
POST es/_search { "query": { "bool": { "must": [ { "match": { "name": "李" } } ] } } }filter 查找名称含有李字的人
POST es/_search { "query": { "bool": { "filter": [ { "match": { "name": "李" } } ] } } }must_not 查找名称含有李字但是年龄里不包含20岁的人
POST es/_search { "query": { "bool": { "must": [ { "match": { "name": "李" } } ], "must_not": [ { "term": { "teamConferenceEn": { "age": "20" } } } ] } } }should 应该查找名称包含李,年龄在11-22之间但是不包含20岁的人。但是不在11岁到22岁之间的人也可能出现,因为这只是应该,要以must为准。
但是如果设置了"minimum_should_match": 1这个参数的话,就表示should条件里必须达到指定的次数,才能返回。即不在11-22岁之间的就不可能出现了。
如果后面配置的是一个比例,如75%,然后有5条should条件,则5*0.75 = 3.75,向下取整为3次,即满足其中3个条件也会返回
POST es/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"name": "李"
}
}
],
"must_not": [
{
"term": {
"teamConferenceEn": {
"age": "20"
}
}
}
],
"should": [
{
"range": {
"age": {
"gte": 11,
"lte": 22
}
}
}
],
"minimum_should_match": 1
}
}
}五、排序查询
从大到小是desc,从小到大是asc 与mysql一样,支持多个排序
POST es/_search
{
"query": {
"match": {
"team_name": "研发部"
}
},
"sort": [
{
"playYear": {
"order": "desc"
}
}
]
}六、聚合查询
聚合分析是数据库中重要的功能特性,完成对⼀个查询的数据集中数据的聚合计算,如:找出某字段(或计算表达式的结果)的最⼤值、最⼩值,计算和、平均值等。ES作为搜索引擎兼数据库,同样提供了强⼤的聚合分析能⼒。
对⼀个数据集求最⼤、最⼩、和、平均值等指标的聚合,在ES中称为指标聚合
⽽关系型数据库中除了有聚合函数外,还可以对查询出的数据进⾏分组group by,再在组上进⾏指标聚合。在ES中称为桶聚合
七、指标聚合
- max min sum avg 最大值,最小值,求和,平均值
aggs表示使用聚合函数,avgAge为自定义名称,avg为函数名
POST es/_search
{
"query": {
"term": {
"team_name": {
"value": "研发部"
}
}
},
"aggs": {
"avgAge": {
"avg": {
"field": "age"
}
}
},
"size": 0
}value_count 统计⾮空字段的⽂档数
POST es/_search { "query": { "term": { "team_name": { "value": "研发部" } } }, "aggs": { "countPlayerYear": { "value_count": { "field": "playYear" } } }, "size": 0 }
还有专门支持统计的请求,统计研发部的人数:
POST es/_count
{
"query": {
"term": {
"team_name": {
"value": "研发部"
}
}
}
}- Cardinality 值去重计数
去重,将工龄相同的去重
POST es/_search
{
"query": {
"term": {
"team_name": {
"value": "研发部"
}
}
},
"aggs": {
"countPlayerYear": {
"cardinality": {
"field": "playYear"
}
}
},
"size": 0
}stats 统计count max min avg sum 5个值
POST es/_search { "query": { "term": { "team_name": { "value": "研发部" } } }, "aggs": { "stats_playYear": { "stats": { "field": "playYear" } } }, "size": 0 }Extended stats ⽐stats多4个统计结果: 平⽅和、⽅差、标准差、平均值加/减两个标准差的区间
POST es/_search { "query": { "term": { "team_name": { "value": "研发部" } } }, "aggs": { "stats_playYear": { "extended_stats": { "field": "playYear" } } }, "size": 0 }Percentiles 占⽐百分位对应的值统计,默认返回[ 1, 5, 25, 50, 75, 95, 99 ]分位上的值
POST es/_search { "query": { "term": { "team_name": { "value": "研发部" } } }, "aggs": { "pecentAge": { "percentiles": { "field": "age" } } }, "size": 0 }
查找指定分位上的值,指定20,50,75分位上的数
POST es/_search
{
"query": {
"term": {
"team_name": {
"value": "研发部"
}
}
},
"aggs": {
"percentAge": {
"percentiles": {
"field": "age",
"percents": [
20,
50,
75
]
}
}
},
"size": 0
}八、桶聚合
类似mysql的group by分组然后聚合
- Terms Aggregation 根据字段项分组聚合
根据年龄进行分组
POST es/_search
{
"query": {
"term": {
"team_name": {
"value": "研发部"
}
}
},
"aggs": {
"aggsAge": {
"terms": {
"field": "age",
"size": 10
}
}
},
"size": 0
}- order 分组聚合排序
研发部根据年龄进行分组,分组信息通过年龄排序
POST es/_search
{
"query": {
"term": {
"team_name": {
"value": "研发部"
}
}
},
"aggs": {
"aggsAge": {
"terms": {
"field": "age",
"size": 10,
"order": {
"_key": "desc"
}
}
}
},
"size": 0
}研发部根据年龄进行分组,分组信息通过年龄所在组的文档数量排序
POST es/_search
{
"query": {
"term": {
"team_name": {
"value": "研发部"
}
}
},
"aggs": {
"aggsAge": {
"terms": {
"field": "age",
"size": 10,
"order": {
"_count": "desc"
}
}
}
},
"size": 0
}所有人按照部门的平均年龄进行分组排序,order里可以指定聚合函数
POST es/_search
{
"aggs": {
"aggsTeamName": {
"terms": {
"field": "team_name",
"size": 30,
"order": {
"avgAge": "desc"
}
},
"aggs": {
"avgAge": {
"avg": {
"field": "age"
}
}
}
}
},
"size": 0
}- 筛选分组聚合
精确查询选择或排除指定的数据进行分组。include选择指定的数据,exclude排除不想要的数据
POST es/_search
{
"aggs": {
"aggsTeamName": {
"terms": {
"field": "team_name",
"include": [
"研发部",
"人力资源部",
"aaaa"
],
"exclude": [
"aaaa"
],
"size": 30,
"order": {
"avgAge": "desc"
}
},
"aggs": {
"avgAge": {
"avg": {
"field": "age"
}
}
}
}
},
"size": 0
}根据正则表达式筛选分组
POST es/_search
{
"aggs": {
"aggsTeamName": {
"terms": {
"field": "teamNameEn",
"include": ".*部|aaa",
"exclude": "aaa",
"size": 30,
"order": {
"avgAge": "desc"
}
},
"aggs": {
"avgAge": {
"avg": {
"field": "age"
}
}
}
}
},
"size": 0
}- Range Aggregation 范围分组聚合
根据范围进行分组,from类似>=,to类似<。key的话是指定别名
POST es/_search
{
"aggs": {
"ageRange": {
"range": {
"field": "age",
"ranges": [
{
"to": 20,
"key": "A"
},
{
"from": 20,
"to": 35,
"key": "B"
},
{
"from": 35,
"key": "C"
}
]
}
}
},
"size": 0
}- Date Range Aggregation 时间范围分组聚合
根据出生日期范围进行分组
POST es/_search
{
"aggs": {
"birthDayRange": {
"date_range": {
"field": "birthDay",
"format": "MM-yyy",
"ranges": [
{
"to": "01-1989"
},
{
"from": "01-1989",
"to": "01-1999"
},
{
"from": "01-1999",
"to": "01-2009"
},
{
"from": "01-2009"
}
]
}
}
},
"size": 0
}- Date Histogram Aggregation 时间柱状图聚合
按天、⽉、年等进⾏聚合统计。可按 year (1y), quarter (1q), month (1M), week (1w), day (1d), hour (1h), minute (1m), second (1s) 间隔聚合
按年统计:interval已经被弃用,使用calendar_interval
POST es/_search
{
"aggs": {
"birthday_aggs": {
"date_histogram": {
"field": "birthDay",
"format": "yyyy",
"calendar_interval": "year"
}
}
},
"size": 0
}九、query string查询
语法查询,可以直接⽤lucene查询语法写⼀个查 询串进⾏查询,ES中接到请求后,通过查询解析器,解析查询串⽣成对应的查询。
单字段,查询名字带有张和三和人
POST es/_search
{
"query": {
"query_string": {
"default_field": "name",
"query": "张 OR 三"
}
},
"size": 100
}多字段,查询名字或部门带有张和三和人
POST es/_search
{
"query": {
"query_string": {
"fields": [
"name",
"team_name"
],
"query": "张 OR 三"
}
},
"size": 100
}十、索引别名
在开发中,随着业务需求的迭代,较⽼的业务逻辑就要⾯临更新甚⾄是重构,⽽对于es来说,为了适应新的业务逻辑,可能就要对原有的索引做⼀些修改,⽐如对某些字段做调整,甚⾄是重建索引。 ⽽做这些操作的时候,可能会对业务造成影响,甚⾄是停机调整等问题。由此,es提供了索引别名来解决这些问题。 索引别名就像⼀个快捷⽅式或是软连接,可以指向⼀个或多个索引,也可以给任意⼀个需要索引名的API来使⽤。 别名的应⽤为程序提供了极⼤地灵活性
操作别名的请求是
POST /_aliases查询别名
#查询指定索引的别名 GET /es/_alias #根据别名查找数据,如果一个别名对应多个索引,则会查询出多个索引。但是在查询单个文档的时候会报错,因为系统不知道查询的别名对应哪一个索引 GET /_alias新增别名
POST /_aliases { "actions": [ { "add": { "index": "es", "alias": "es_v1.0" } } ] }
或者通过以下方式
PUT /es/_alias/es_v1.1删除别名
POST /_aliases { "actions": [ { "remove": { "index": "es", "alias": "es_v1.0" } } ] }
或者通过以下方式
DELETE /es/_alias/es_v1.1- 重命名
即删除再新增
POST /_aliases
{
"actions": [
{
"remove": {
"index": "es",
"alias": "es_v1.0"
}
},
{
"add": {
"index": "es",
"alias": "es_v2.0"
}
}
]
}- 为多个索引指定一个别名
这里需要注意如果需要通过别名进行写操作,要在指定的索引上加上"is_write_index": true这个条件
POST /_aliases
{
"actions": [
{
"add": {
"index": "es",
"alias": "esalias",
"is_write_index": true
}
},
{
"add": {
"index": "es1",
"alias": "esalias"
}
}
]
}同个索引指定多个别名
POST /_aliases { "actions": [ { "add": { "index": "nba", "alias": "nba_v2.1" } }, { "add": { "index": "nba", "alias": "nba_v2.2" } } ] }通过别名写索引
POST /esalias/_doc/10 { "name": "张三", "team_name": "部门", "position": "岗位", "play_year": "工龄", "jerse_no": "工号" }
十一、重建索引
Elasticsearch是⼀个实时的分布式搜索引擎,为⽤户提供搜索服务,当我们决定存储某种数据时,在创建索引的时候需要将数据结构完整确定下来,于此同时索引的设定和很多固定配置将⽤不能改变。 当需要改变数据结构时,就需要重新建⽴索引,为此,Elastic团队提供了很多辅助⼯具帮助开发⼈员进⾏重建索引。
es的重建索引依赖别名,因为正常情况下是使用别名进行索引的使用。索引通过重新指向别名就能够进行一个类似索引重建的目的。本质上不是修改原索引结构
Es取⼀个别名es_latest, es_latest作为对外使⽤
新增⼀个索引es_20200101,结构复制于es索引,根据业务要求修改字段,索引后面跟随日期
将es数据同步到es_20200101
给es_20200101添加别名es_latest,删除es别名es_latest
删除es索引(有必要,旧的索引数据会占用资源)
复制索引数据:wait_for_completion=false 表示是否进行异步复制数据,如果数据量很大的时候,需要进行一个异步等待操作。会返回一个任务的id
POST /_reindex?wait_for_completion=false
{
"source": {
"index": "nba"
},
"dest": {
"index": "nba_20220101"
}
}十二、refresh刷新缓冲区
新的数据在添加以后,es是会先读取到缓冲区,然后在一定的时间(默认1s)才会刷新数据
强制刷新:在添加的时候加上参数refresh
curl -X PUT localhost:9200/es1/_doc/888?refresh -H 'Content-Type:
application/json' -d '{ "name": "蔡徐坤" }'
curl -X GET localhost:9200/es1/_doc/_search?pretty默认刷新时间是1s,修改默认刷新时间
PUT /star/_settings
{
"index": {
"refresh_interval": "5s"
}
}关闭refresh
PUT /es/_settings
{
"index": {
"refresh_interval": "-1"
}
}十三、高亮展示
如果返回的结果集中很多符合条件的结果,那怎么能⼀眼就能看到我们想要的那个结果
默认高亮查询:默认高亮的字符用<em></em>包住
POST /es_latest/_search { "query": { "match": { "team_name": "部" } }, "highlight": { "fields": { "team_name": {} } } }自定义高亮查询:pre_tags表示第一个标签,post_tags表示第二个标签
POST /nba_latest/_search { "query": { "match": { "team_name": "部" } }, "highlight": { "fields": { "displayNameEn": { "pre_tags": [ "<h1>" ], "post_tags": [ "</h1>" ] } } } }
十四、查询建议
查询建议,是为了给⽤户提供更好的搜索体验。包括:词条检查,⾃动补全。
| 字段 | 说明 |
| ------------ | ------------------------------------------------------------ |
| text | 指定搜索文本 |
| field | 获取建议词的搜索字段 |
| analyzer | 指定分词器 |
| size | 每个词返回的最大建词数 |
| sort | 如何对建议词进行排序:score:先按评分排序、再按文档频率排、term顺序。frequency:先按文档频率排序,再按评分、term顺序排 |
| suggest_mode | 建议模式,控制提供建议词的方式:missing:默认方式,仅在搜索的词项在索引中不存在时才提供建议词。popular:仅建议文档频率比搜索词项高的词。aways:总是提供匹配的建议词 |
- Term suggester
term 词条建议器,对给输⼊的⽂本进⾏分词,为每个分词提供词项建议。
POST /es/_search
{
"suggest": {
"my-suggestion": {
"text": "jaav",
"term": {
"suggest_mode": "missing",
"field": "position"
}
}
}
}- Phrase suggester
phrase 短语建议,在term的基础上,会考量多个term之间的关系,⽐如是否同时出现在索 引的原⽂⾥,相邻程度,以及词频等
POST /es/_search
{
"suggest": {
"my-suggestion": {
"text": "jaav",
"phrase": {
"field": "position"
}
}
}
}- Completion suggester
Completion 完成建议,这里必须要字段类型为completion才可以使用
POST /es/_search
{
"suggest": {
"my-suggestion": {
"text": "jaav",
"completion": {
"field": "position"
}
}
}
}