ES深入浅出系列(六)使用ES操作时候需要注意的几个坑
===========================
本篇主要记录些在使用ES操作时候容易踩中的坑,对于非常熟悉ES的朋友来说可能比较基础,主要是一些ES操作的查漏补缺。
新增数据没有指定id情况
在使用kibanna面板操作es的时候,如果忘记指定id,通常es里面会默认生成一个id,如果你希望es的每条记录都使用自己生成的唯一id,那么就需要手动加上。下边是两种写法的差异:
指定id类型
POST /user/_doc/1
{
"username":"idea-01",
"tel":"1867192323",
"sex":"1",
"registryTime":"2000-10-01 10:11:00",
"updateTime":"2024-04-05 11:00:00"
}
未指定id类型
POST /user/_doc
{
"username": "idea-01",
"tel": "1867192323",
"sex": "1",
"registryTime": "2000-10-01 10:11:00",
"updateTime": "2024-04-05 11:00:00"
}
未指定index时扫描了全部索引
当我们在进行搜索的时候,如果没有指定index,默认会发生全部索引的扫描,示例代码如下:
GET /_search
之所以介绍这个,是因为之前在工作中见到一段es查询特别慢的代码,当时是使用了ResthighlevelClient组件去查询es的内容,但是没有传递进去index的名称,导致扫描了所有的index,虽然可以查出来数据,但是性能非常差。
URL模式请求和RequestBody方式请求
ES是可以支持走Http协议访问的,因此常用的方式有两种,一种是在URL后边拼接后缀请求,一种是走请求体访问。
URL访问方式有以下几种方式:
1.泛查询
查询es中所有字段中,包含有idea-11内容的文档记录
GET /user_info/_search?q=idea-11
2.指定字段查询
查询username字段包含特定值的文档记录,但是要注意,这里会把idea-11
拆成多个关键字进行匹配,具体的拆解策略和使用的分词器有关系
GET /user_info/_search?q=username:idea-11
如果你希望精确查询,走下边的这段sql:
GET /user_info/_search?q=username:"idea-11"
3.多关键字查询语法
- q:查询的字符串
- df:查询哪个字段
- size: 查询多少条记录
- from:从第几条开始查
- sort:排序方式
GET /user_info/_search?q=username:idea-11&&size=1&&from=2&&sort=_id:asc
基于RequestBody的查询方式会复杂很多。
1.只返回特定字段
GET /user_info/_search
{
"_source": ["username","tel"]
}
2.painless语法
支持脚本逻辑的嵌入,例如需要对返回的值做一定的处理。
GET /user_info/_search
{
"script_fields": {
"new_field": {
"script": {
"lang": "painless",
"source": "doc['username'].value+'hello'"
}
}
},
"query": {
"match_all": {}
}
}
但是需要注意,使用painless操作的字段要预先设置改字段的fielddata值为true才可以。
PUT /user_info/_mapping
{
"properties": {
"username": {
"type": "text",
"fielddata": true
}
}
}
基于RequestBody的AND,OR语法
OR查询
默认ES里面如果你检索的关键字可以拆解成多个Token,它都会给你拆解出来,然后做或的检索。例如下边这段检索代码:
GET /user_info/_search
{
"query": {
"match": {
"username": "idea is here"
}
}
}
AND查询
代码如下:
GET /user_info/_search
{
"query": {
"match": {
"username": {
"query":"idea is here",
"operator": "and"
}
}
}
}
AND和OR组合使用查询
这种使用场景还是比较多的,可以参考以下示例:
GET /user_info/_search
{
"query":{
"query_string": {
"default_field": "username",
"query": "(idea AND there) OR (idea AND here)"
}
}
}
这种写法需要注意,AND和OR关键字需要大写才行。
常用的批量操作API
bulk操作
bulk操作可以实现批量发送语句内容给到es服务端,但是每个语句的前后执行不具备事务完整性的保护,所以可能出现第一条语句执行失败,但是第二条语句执行成功的情况。例如下边这段代码:
POST _bulk
{ "index" : { "_index" : "user_info", "_id" : "10" } }
{"username":"idea-10"} //如果存在id=10的记录,就更新username,否则插入
{ "index" : { "_index" : "user_info", "_id" : "11" } }{"username":"idea-11"} //如果存在id=11的记录,就更新username,否则插入
{"delete":{"_index":"user_info","_id":"id=5"}}
mget命令
批量返回一些内容,减少网络IO
GET _mget
{
"docs":[
{"_index":"user_info","_id":11},
{"_index":"user_info","_id":10}
]
}
msearch命令
批量检索内容,也是为了减少网络IO
POST /_msearch
{ "index":"user_info"}
{ "query":{"match_all":{}},"size":1}
{ "index":"user_info"}
{ "query":{"match":{"username":"idea-11"}},"size":2}
给索引新增字段
新增普通字段:
PUT /user_info/_mapping
{
"properties": {
"hight": {
"type": "integer"
}
}
}
新增嵌套字段:
PUT /user_info/_mapping
{
"properties": {
"school": {
"type": "keyword",
"norms": false,
"doc_values": false
},
"teacher": {
"type": "nested",
"properties": {
"rightStatus": {
"type": "keyword",
"norms": false,
"doc_values": false
},
"rightCurrTime": {
"type": "keyword",
"norms": false,
"doc_values": false
}
}
}
}
}
原文链接: https://juejin.cn/post/7357205817252610057
文章收集整理于网络,请勿商用,仅供个人学习使用,如有侵权,请联系作者删除,如若转载,请注明出处:http://www.cxyroad.com/17274.html