前言
该文章最好要有一点REST风格API的知识。
操作是ES配置Kibana进行使用。
基本的REST命令说明
method | url地址 | 说明 |
---|---|---|
PUT | localhost:9200/索引名称/类型名称/文档Id | 创建文档(指定文档Id) |
POST | localhost:9200/索引名称/类型名称 | 创建文档(随机文档Id) |
POST | localhost:9200/索引名称/类型名称/文档Id/_update | 修改文档 |
DELETE | localhost:9200/索引名称/类型名称/文档Id | 删除文档 |
GET | localhost:9200/索引名称/类型名称/文档Id | 通过文档Id查询文档 |
POST | localhost:9200/索引名称/类型名称/_search | 查询该类型下所有数据 |
索引相关操作
新增索引
命令:
#PUT /索引名
PUT /test_create_index #创建一个名为test_create_index 索引
创建成功。并且主分片个数为1,复制分片个数为1,文档个数为0。
新增索引时指定某些字段的映射:
有时在创建索引时需要对某些特定字段类型进行映射,比如年龄字段要设置为整形等,这样就避免了ES进行猜类型。
PUT /test_create_index1
{
"mappings": {
"properties": {
"name":{ #name字段设置为text类型
"type": "text"
},
"age":{ #age字段设置为int类型
"type": "integer"
}
}
}
}
这样在进行文档新增时,如果age属性不是int类型,就会新增失败,如上图。
创建索引都某些字段指定分词器
PUT /test_create_index4
{
"mappings": {
"properties": {
"name":{
"analyzer": "ik_max_word", #指定name属性使用ik_max_word分词器进行分词。
"type": "text"
}
,
"desc":{
"type": "keyword" #keyword类型的字段不能指定分词器,因为该类型不会进行分词。
}
}
}
}
查看索引信息
GET /索引名
GET /test_create_index1
获取ES的很多信息
GET _cat/xxxx
xxxxx不同就可以获取ES不同的信息
#获取ES的所有索引
GET _cat/indices
#获取ES的master节点的信息
GET _cat/master
#还有很多很多信息 Kibana会有提示。
删除索引
DELETE /索引名
文档相关操作
添加文档:
PUT /索引名/类型/文档ID
根据Id查询文档
GET /索引名/类型/文档Id
修改文档
不推荐方法
PUT /索引名/类型/文档Id
{
文档内容
}
修改文档的name属性,但是,这种修改方式有一个弊端,那就是类似于把文档删了重建,如果你在修改的内容上只指定部分属性,那么没指定的属性就会没有了。
如下图:
因为修改时没有指定age属性,所以属性不见了。
推荐方法:
POST /索引名/类型/文档ID/_update
{
"doc":{ #doc是固定的
##要修改的属性
}
}
只指定了age属性,但是name属性也没有被清空。所以推荐这种修改文档的方法。
删除文档
DELETE /索引名/类型/文档Id
各种查询
查询所有文档
查询某索引下的所有文档
GET /索引名/_search #查询某索引下的所有文档
GET /索引名/类型/_search #查询某类型下的所有文档
简单过滤文档
#q代表query的意思,是固定的
GET /索引名/_search?q=属性:值
复杂查询
GET /索引名/_search
{
##查询参数体
}
查询name属性带令的文档。
查询文档的指定字段
比如指向查询name和age字段
GET /索引名/_search
{
"_source":[要查询的字段名数组]
}
对查询结果进行排序
GET /索引名/_search
{
"sort":{
"字段名":{
"order":"asc/desc"
}
}
}
按年龄降序排序。
分页查询
GET /索引名/_search
{
"from":x, #起始
"size":x #显示多少条数据
}
#与数据库sql的 limit offset limit 一样 from=limit limit=size 从零开始
只查询一条数据
多条件查询
语法:
boost、filter、minimum_should_match、must、must_not、should 分别代表了条件间关系和一些过滤信息等功能。
查出名字带有令并且年龄等于18的。 must表示and的意思
查出名字带有令或者年龄等于18的。should代表or
查出年龄不等于18的。must_not代表不等于
范围查询年龄在5-18岁的人
gte : 大于等于
lte:小于等于
gt:大于
lt:小于
多个值查询,用空格隔开
查询名字带有令或者孙的。
精确查询
term查询是直接通过倒排索引指定的词条进行文档的精确查询的,无需扫描所有文档,速度会快很多。
term:直接用查询的词条(不进行分词),然后用ES维护好的倒排索引进行直接定位到指定文档返回。
match:先把查询的词条进行分词,然后扫描所有文档,把每个文档的值进行匹配。
倒排索引就像是维护了一个map,key是新建文档时,使用分词器进行分词出来的若干词条,value是文档包含该词条的文档Id的集合。使用key可以直接定位到value,然后返回文档Id。
而match就是相当于遍历一个文档数组,每个都拿出来比较。
ElasticSearch的字符串有两种类型:
text:该字符串类型的属性会被分词器进行分析。
keyword:该字符串类型的属性代表的就是一个关键字,所以不会被分词器进行分析,直接整串匹配。
测试:
- 创建索引并指定字段的类型和分词器:name属性设置为text并使用IK分词器进行分词,desc属性设置为keyword属性。
PUT /test_create_index4
{
"mappings": {
"properties": {
"name":{
"analyzer": "ik_max_word", #指定name属性使用ik_max_word分词器进行分词。
"type": "text"
}
,
"desc":{
"type": "keyword" #keyword类型的字段不能指定分词器,因为该类型不会进行分词。
}
}
}
}
- 添加两个文档
PUT /test_create_index4/_doc_1/1
{
"name" : "令狐冲",
"desc" : "笑傲江湖第一人"
}
PUT /test_create_index4/_doc_1/2
{
"name" : "令狐冲他哥",
"desc" : "笑傲江湖第一人他哥"
}
- 使用ik_max_word分词器分别对两个文档的name属性值进行分词,查看结果。我这里的IK分词器已经修改了词典,把令狐冲看作一个词,如果你没修改,可能得到的分词结构就不是这样的。
所以这两个文档构建的name字段的倒排索引目录大概为(这里是简略版,真正的倒排索引的数据结构要比这复杂):
共有词:令狐冲、令狐、冲、他、哥
所以:
词条 | 文档 |
---|---|
令狐冲 | 1,2 |
令狐 | 1,2 |
冲 | 1,2 |
他 | 2 |
哥 | 2 |
查询:
令狐冲,直接去倒排索引查,查到文档1,2都含有,就直接返回文档1,2的内容。
冲、令狐都能查到,因为倒排索引里面都有该词条。
输入“令”、“令狐冲他哥”都查不到数据,因为倒排索引中没有“令”和“令狐冲他哥”的词条。因为term查询不会对输入进行分词。
测试keyword类型:
因为desc属性时keyword类型,所以分词器不会对该属性的值进行分词。
所以对desc属性建立的倒排索引为:
词条 | 文档 |
---|---|
笑傲江湖第一人 | 1 |
笑傲江湖第一人他哥 | 2 |
查询:
查询结果高亮
主要是对查询结果使用HTML标签或者CSS样式进行高亮展示:
GET /test_create_index4/_search
{
"highlight": {
"fields": {
"name": {} #对name属性进行高亮
}
}
}
默认使用<em>标签进行高亮
自定义高亮展示的样式:
GET /test_create_index4/_search
{
"highlight": {
"fields": {
"name": {} #对name属性进行高亮
}
"pre_tags": "<p style='color:red;'>" #开始标签
, "post_tags": "</p>" #结束标签
}
}