Skip to content

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"
            }
        }
    }
}