随笔 - 145  文章 - 0  评论 - 6  阅读 - 18万

Elasticsearch基本操作

索引操作

创建索引

PUT /user

查询指定索引

GET /user

查询所有索引信息

GET _cat/indices?v

删除索引

DELETE /user

类型映射

动态映射

在关系型数据库中,得先创建表,指定字段和字段类型,才能将数据插入表中。

elasticsearch默认情况下不需要先创建索引,指定mapping,就可以插入数据。会自动推断数据类型

PUT /user/_doc/1
{
	"userId": 1,
	"name": "zhang san",
	"age": 20,
	"birthday": "2022-08-20"
}

对于以上语句,如果索引user不存在,会先创建索引user,且自动推断字段类型,然后新增一条id=1的数据。

如果索引已经存在,多出来的字段,则会自动增加到mapping中。

查询下索引mapping信息

GET /user/_mapping

{
  "user" : {
    "mappings" : {
      "properties" : {
        "age" : {
          "type" : "long"
        },
        "birthday" : {
          "type" : "date"
        },
        "name" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "userId" : {
          "type" : "long"
        }
      }
    }
  }
}

会看到elasticsearch自动推断出数据字段类型

字段 类型
id long
name text/keyword
age long
birthday date

再次新增一条docId=2的数据

PUT /user/_doc/2
{
	"userId": 2,
	"name": "zhang san",
	"age": 20,
	"birthday": "2022-08-20",
	"createTime": "2023-08-20 12:00:00"
}

此时索引已经存在,但是多了createTime这个字段,会把createTime增加到mapping中。

再次查询索引mapping,可以看到createTime字段。

GET /user/_mapping

{
  "user" : {
    "mappings" : {
      "properties" : {
        "age" : {
          "type" : "long"
        },
        "birthday" : {
          "type" : "date"
        },
        "createTime" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "name" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "userId" : {
          "type" : "long"
        }
      }
    }
  }
}

指定映射

使用如下语句便可以在创建索引时指定字段以及类型

PUT /user
{
  "mappings": {
    "properties": {
      "userId": {
        "type": "integer",
        "index": true
      },
      "name": {
        "type": "text",
        "index": true
      },
      "age": {
        "type": "integer",
        "index": true
      },
      "birthday": {
        "type": "date",
        "index": true
      }
    }
  }
}

其中: "index": true表示该列可以作为查询条件,可以省略,默认为true

查询映射

GET /user/_mapping

查询指定字段映射

GET /user/_mapping/field/userId

增加字段映射

PUT /user/_mapping
{
  "properties": {
    "createTime": {
      "type": "date",
      "index": false,
      "format": "yyyy-MM-dd HH:mm:ss"
    }
  }
}

增加了一个创建时间

改变字段映射类型

比如想把createTime改成long类型,目前不支持此种操作,因为可能会使得已有数据无效

dynamic参数设置

  • true,默认值,即动态映射,自动推断字段和类型,创建mapping
  • false,非动态模式,无法根据输入文档的内容,自动创建mapping,需要手动创建mapping
  • strict,严格模式,同非动态模式,区别在于,非动态模式,输入的文档中如果有字段不在mapping中,依然可以存储和读取,但是该字段不在mapping中,因此也无法根据该字段进行检索;但严格模式,无法存储,会直接报错,严格模式实际上就类似于关系型数据库中的表了。

语法如下所示:

创建索引同时指定mapping

PUT /user/
{
  "mappings": {
    "dynamic": "strict",
    "properties": {
      "userId": {
        "type": "long"
      }
    }
  }
}

文档基本操作

新增或者修改文档

PUT | POST /索引名称/_doc/docId

其中PUT必须指定id,POST若不指定,则会自动生成随机ID,在带id参数路径是,PUT和POST语义一样。

在指定id时,若id不存在则新增,否则修改(修改的是所有字段,若请求体没有包含某个字段,则该字段不会再保存,将查询不到)。

POST方法不带id时,因为会自动生成随机id,所以每次都是新增。

指定id方式(PUT或者POST)

PUT /user/_doc/1
{
	"userId": 1,
	"name": "zhang san",
	"age": 20,
	"birthday": "2022-08-20",
	"createTime": "2022-08-20 12:10:30"
}

随机ID(POST),当然了POST方式也可以指定ID

POST /user/_doc
{
	"userId": 1,
	"name": "zhang san",
	"age": 20,
	"birthday": "2022-08-20",
	"createTime": "2022-08-20 12:10:30"
}

进行修改,故意少写createTime

PUT /user/_doc/1
{
	"userId": 1,
	"name": "zhang san",
	"age": 25,
	"birthday": "1997-08-20"
}

查询结果(createTime会丢失)

{
	"userId": 1,
	"name": "zhang san",
	"age": 25,
	"birthday": "1997-08-20"
}

新增文档

使用_create方式,如果id存在,会报错。

PUT /user/_create/1
{
	"userId": 1,
	"name": "zhang san",
	"age": 20,
	"birthday": "2022-08-20",
	"createTime": "2022-08-20 12:10:30"
}

修改文档

使用_update方式,可以修改指定的字段,若id不存在,会报错

仅仅修改age字段

POST /user/_update/1
{
  "doc": {
    "age": 25
  }
}

或者

POST /user/_doc/1/_update
{
  "doc": {
    "age": 25
  }
}

查看文档

GET /user/_doc/1

删除文档

DELETE /user/_doc/1

批量操作

使用_bulk API

包含四种操作,可以同时存在

  • index,存在则修改,否则新增
  • create,新增
  • update,修改
  • delete,删除

下面对user索引批量新增文档,注意,除了delete不需要紧跟数据,其它操作都需要接一条数据,无论是操作还是数据,都是一行完成。

POST /user/_bulk
{"index": {"_id": 1}}
{"userId": 1, "name" : "zhang san", "age" : 20, "birthday" : "2021-08-20", "createTime" : "2022-08-20 12:10:30"}
{"index": {"_id": 2}}
{"userId": 2, "name" : "li si", "age" : 20, "birthday" : "2022-08-20", "createTime" : "2022-08-20 12:10:30"}
{"index": {"_id": 3}}
{"userId": 3, "name" : "zhang san shuo", "age" : 25, "birthday" : "2022-08-20", "createTime" : "2022-08-20 12:10:30"}
{"index": {"_id": 4}}
{"userId": 4, "name" : "wang wu", "age" : 20, "birthday" : "2021-08-20", "createTime" : "2022-08-20 12:10:30"}

文档搜索

查找所有

GET /user/_search

或者

GET /user/_search
{
    "query": {
        "match_all": {}
     }
}

简单查询

注意,对于类型为text的列,会进行分词

假设现在有以下数据

[
    {
          "userId" : 1,
          "name" : "zhang san",
          "age" : 20,
          "birthday" : "2022-08-20",
          "createTime" : "2022-08-20 12:10:30"
     },
    {
          "userId" : 2,
          "name" : "li si",
          "age" : 20,
          "birthday" : "2022-08-20",
          "createTime" : "2022-08-20 12:10:30"
     }
]

现在根据名称查询

GET /user/_search
{
    "query": {
        "match": {
          "name": "zhang"
        }
     }
}

会找到zhang san那条记录

GET /user/_search
{
    "query": {
        "match": {
          "name": "zhang li"
        }
     }
}

会找到zhang sanli si两条记录,因为搜索条件会被分词为zhangli两个词

如果想要搜索条件作为整体出现,可以使用match_phrase

如以下例子

GET /user/_search
{
    "query": {
        "match_phrase": {
          "name": "zhang li"
        }
     }
}

该命令将不会查到任何结果,因为没有任何记录的名字包含zhang li

继续增加一条数据,假设目前的结果如下

[
    {
          "userId" : 1,
          "name" : "zhang san",
          "age" : 20,
          "birthday" : "2022-08-20",
          "createTime" : "2022-08-20 12:10:30"
     },
    {
          "userId" : 2,
          "name" : "li si",
          "age" : 20,
          "birthday" : "2022-08-20",
          "createTime" : "2022-08-20 12:10:30"
     },
    {
          "userId" : 3,
          "name" : "zhang san shuo",
          "age" : 25,
          "birthday" : "2022-08-20",
          "createTime" : "2022-08-20 12:10:30"
     }
]

执行以下查询

GET /user/_search
{
    "query": {
        "match_phrase": {
          "name": "zhang san"
        }
     }
}

将会得到zhang san以及zhang san shuo两条记录,因为这两条记录的名字都包含zhang san

match_phrase匹配逻辑:首先也会将搜索条件进行分词,并且每个词都要命中记录,且分词的相对位置也要一样。比如搜索zhang shuo是不会匹配到zhang san shuo这条记录的,因为顺序不一致,中间还有一个san,虽然分词zhangshuo都能命中。

范围查询

GET /user/_search
{
  "query": {
    "range": {
      "age": {
        "gte": 10,
        "lte": 20
      }
    }
  }
}

复杂查询

must = and,should = or

查找名字包含zhang san,年龄为25的记录

GET /user/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match_phrase": {
            "name": "zhang san"
          }
        },
        {
           "match": {
            "age": 25
          }
        }
      ]
    }
  }
}

得到结果为name=zhang san shuo,age=25的记录

查找名字包含zhang san或者年龄为25的记录

GET /user/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "match_phrase": {
            "name": "zhang san"
          }
        },
        {
           "match": {
            "age": 25
          }
        }
      ]
    }
  }
}

得到结果为name=zhang san shuo,age=25的记录以及name=zhang san,age=20的记录

查找(name like '%zhang san%' or age = 25) and birthday = '2022-08-20'

GET /user/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "birthday": "2022-08-20"
          }
        },
        {
          "bool": {
            "should": [
              {
                "match_phrase": {
                  "name": "zhang san"
                }
              },
              {
                "match": {
                  "age": 25
                }
              }
            ]
          }
        }
      ]
    }
  }
}

查找指定列

GET /user/_search
{
    "query": {
        "match_all": {}
     },
     "_source": ["name", "age"]
}

排序

GET /user/_search
{
    "query": {
        "match_all": {}
     },
     "sort": [
       {
         "age": {
           "order": "desc"
         },
         "userId": {
           "order": "asc"
         }
       }
     ]
}

分页

GET /user/_search
{
    "track_total_hits": true,
    "query": {
        "match_all": {}
     },
     "sort": [
       {
         "age": {
           "order": "desc"
         },
         "userId": {
           "order": "asc"
         }
       }
     ],
     "from": 0,
     "size": 2
}

注:

from: 默认为0
size: 默认为10

from + size 的和不能超过10000,这个值由参数max_result_window决定,默认为10000。

"track_total_hits": true,表示返回精确的总数量,否则超过10000条数据时,总数总是返回10000。

posted on   wastonl  阅读(102)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示