ElasticSearch回顾2-这也能增删改查?

ElasticSearch回顾2-这也能增删改查?

我们知道ES是一个搜索引擎,但其实他也能做到实时存储,甚至当一个数据库用

增删改查

又到了大家喜闻乐见的CRUD环节

我们先看看创建

PUT

先插个三条数据康康

PUT /feng666/user/1
{
    
    
  "name": "冯半仙",
  "age": 18,
  "desc": "就这就这?不会还有人0offer吧",
  "tags":["菜","穷","丑"]
}



PUT /feng666/user/2
{
    
    
  "name": "冯大仙",
  "age": 22,
  "desc": "哦原来是我自己啊",
  "tags":["很菜","很穷","也不帅"]
}


PUT /feng666/user/3
{
    
    
  "name": "马云",
  "age": 55,
  "desc": "还不来修福报啊",
  "tags":["996","福报","奋斗"]
}

查看数据

GIF 2020-10-20 20-37-47

注:

执行命令时,若数据不存在,则新增该条数据,如果存在则修改这条数据

GET

我们可以用GET查询,获得数据

image-20201020204214670

如果想修改,则put直接覆盖

PUT /feng666/user/1
{
    
    
  "name": "冯半仙",
  "age": 18,
  "desc": "就这就这?不会还有人0offer吧",
  "tags":["不菜","不算穷","不算太丑"]
}

GIF 2020-10-20 20-44-03

如果更改一部分,还得把之前的全部写一遍,也太麻烦了,这不合理。

img

那我们可以试一下post来更新数据

POST

我们使用 POST 命令,在 id 后面跟 _update ,要修改的内容放到 doc 文档(属性)中即可。

POST /feng666/user/1
{
    
    
  "doc":{
    
    
    "name": "冯半仙666",
    "desc":"别骂了别骂了"
  }
}

运行结果

GIF 2020-10-20 20-49-14

查询

刚才就知道了,查询用GET就完事儿了

比如查第一条数据,

GET /feng666/user/1

那如果条件查询呢?把字段加入 _search?q=

GET /feng666/user/_search?q=name:冯半仙666
GET /feng666/user/_search?q=name:马云

通过 _serarch?q=name:冯半仙666 查询条件是name属性有冯半仙666的那些数据。

image-20201020205505548

我们查冯半仙666的时候,发现两个结果都返回了

image-20201020205720454

并且返回值里面有个hits,还有一个_score,得分,分越高表示查询条件匹配度越高

也可以自己构建查询条件

构建查询

GET feng666/user/_search
{
    
    
  "query":{
    
    
    "match":{
    
    
      "name": "冯半仙"
    }
  }
}

返回结果

image-20201020210147991

我们也可以查询全部,怎么查呢?

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

可以发现查出了所有的数据,这里查询不构建条件

就像select * from table_name一样

image-20201020210321765

如果只要select 某个属性 from table_name呢?

继续构建

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

可以发现返回了指定结果

image-20201020210706208

查询结果排序

咱mysql里有order by desc ,那es里呢?一样一样的

构建

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

使用desc和asc分别测试

GIF 2020-10-20 21-12-23

分页查询

GET feng666/user/_search
{
    
    
  "query":{
    
    
    "match_all": {
    
    }
  },
  "sort":[
    {
    
    
      "age":{
    
    
        "order": "asc"
      }
    }
  ],
  "from": 0,
  "size": 1   
}

image-20201020211526396

布尔查询

我们添加一个name也叫冯半仙666的数据,但其他属性不相同

PUT /feng666/user/4
{
    
    
  "name": "冯半仙666",
  "age": 28,
  "desc": "年纪大了,不能加班了",
  "tags":["头发呢","身体不行了","眼圈重"]
}

我们用must查询name是冯半仙666的,但年龄是18岁的

must(and)

image-20201020212042969

查询结果

GIF 2020-10-20 21-22-08

有点像select * from user where name = “冯半仙” and age = 18的意思

那如果是或条件呢?

should(or)

查询name是冯半仙666或者年龄是18的

GET feng666/user/_search
{
    
    
  "query":{
    
    
    "bool": {
    
    
      "should": [
        {
    
    
          "match": {
    
    
            "name": "冯半仙666"
          }
        },
        {
    
    
          "match": {
    
    
            "age": "18"
          }
        }
      ]
    }
  }
}

查询结果

image-20201020213209614

那查询年龄不是18的呢

must_not(not)

GET feng666/user/_search
{
    
    
  "query":{
    
    
    "bool": {
    
    
      "must_not": [
        {
    
    
          "match": {
    
    
            "age": "18"
          }
        }
      ]
    }
  }
}

查询结果

image-20201020213315634

Fitter

查询指定name,age大于18的数据

GET feng666/user/_search
{
    
    
  "query":{
    
    
    "bool": {
    
    
      "must": [
        {
    
    
          "match": {
    
    
            "name": "冯半仙666"
          }
        }
        ],
        "filter":{
    
    
          "range":{
    
    
            "age":{
    
    
              "gt":18
            }
          }
        }
    }
  }
}

gt是大于的写法我们在java里早就接触过了

类似的还有

  • gt 表示大于

  • gte 表示大于等于

  • lt 表示小于

  • lte 表示小于等于

如果是查询25-30岁之间,

GET feng666/user/_search
{
    
    
  "query":{
    
    
    "bool": {
    
    
      "must": [
        {
    
    
          "match": {
    
    
            "name": "冯半仙666"
          }
        }
        ],
        "filter":{
    
    
          "range":{
    
    
            "age":{
    
    
              "gt":25
              , "lt": 30
            }
          }
        }
    }
  }
}

可以发现只返回了一个符合的结果

image-20201020213717301

term精确查询

term查询直接通过倒排索引指定的词条查询的

  • 分词:term直接查询精确的
  • match:会使用分词器解析,先分析文档

注意

我们用的ES7版本中,mappings properties去给多个字段(fields)指定类型的时候,不能给我们的索引指定类型

PUT test2
{
    
    
  "mappings":{
    
    
    "properties":{
    
    
      "name":{
    
    
        "type": "text"
      },
      "desc": {
    
    
        "type": "keyword"
      }
    }
  }
}

//插入数据
PUT test2/_doc/1
{
    
    
  "name": "冯半仙Java name",
  "desc": "冯半仙Java desc"
}

PUT test2/_doc/2
{
    
    
  "name": "冯半仙Java name",
  "desc": "冯半仙Java desc2"
}

在上面的test2索引中,字段name被查询时会被分析器进行分析后匹配查询。但keyword类型不会被分析器处理

测试可得

GET _analyze
{
    
    
  "analyzer": "keyword",
  "text": "冯半仙Java name"
}

运行

image-20201021083123881

可以发现这里简单的字符串,并未被分析,如果改成name属性

GET _analyze
{
    
    
  "analyzer": "standard",
  "text": "冯半仙Java name"
}

运行

image-20201021083234185

总结:keyword不会被分析器分析

GET test2/_search		// text 会被分析器分析查询
{
    
    
  "query": {
    
    
    "term": {
    
    
      "name":  "冯"
    }
  }
}


GET test2/_search		// keyword 不会被分析所以直接查询
{
    
    
  "query": {
    
    
    "match": {
    
    
      "desc": "冯半仙Java desc"
    }
  }
}

两个类型:text keyword —>>> text类型可以被分词器解析,keyword类型不会被分词器解析

term和match查询区别

1、match查询

match是经过分析(analyer)的,也就是说,文档是先被分析器处理了,根据不同的分析器,分析出 的结果也会不同,在会根据分词 结果进行匹配。
并且根据lucene的评分机制(TF/IDF)来进行评分。

2、term查询

term是代表完全匹配,即不进行分词器分析,文档中必须包含整个搜索的词汇

terms

官网API介绍 https://www.elastic.co/guide/cn/elasticsearch/guide/current/_finding_multiple_exact_values.html

再插入两个字段

PUT test2/_doc/3
{
    
    
  "t1": "22",
  "t2": "2020-10-20"
}


PUT test2/_doc/4
{
    
    
  "t1": "33",
  "t2": "2020-10-21"
}

使用精确查询

GET test2/_search
{
    
    
  "query": {
    
    
    "bool": {
    
    
      "should": [
        {
    
    
          "term": {
    
    
            "t1": "22"
          }
        },
        {
    
    
          "term": {
    
    
            "t1": "33"
          }
        }
      ]
    }
  }
}

除了bool查询之外

GET test2/_doc/_search
{
    
    
  "query": {
    
    
    "terms": {
    
    
      "t1": ["22","33"]
    }
  }
}

高亮显示

我们在搜索的时候,会发现查询结果与关键词一致时,关键词会高亮,这是怎么做到的呢?

image-20201021084354741

ES就内置了高亮结果显示的查询,我们知道,浏览器的高亮其实就是给关键字加了一个标签实现的

GET feng666/user/_search
{
    
    
  "query": {
    
    
    "match": {
    
    
      "name": "半仙"
    }
  },
  "highlight": {
    
    
    "fields": {
    
    
      "name": {
    
    }
    }
  }
}

查询后返回的结果

image-20201021084609771

这是es默认的是em标签,我们也可以自定义高亮标签

GET feng666/user/_search
{
    
    
  "query": {
    
    
    "match": {
    
    
      "name": "半仙"
    }
  },
  "highlight": {
    
    
    "pre_tags": "<b class='key' style='color:red'>",
    "post_tags": "</b>", 
    "fields": {
    
    
      "name": {
    
    }
    }
  }
}

运行结果

image-20201021084808725

关于ElasticSearch的学习就到这里,其实总结的在全,也没有官网的API全,技术是学不完的,我们主要是为了提升自己的学习能力,比如看官方文档也能去实现个7788,就是进步。

https://www.elastic.co/guide/cn/elasticsearch/guide/current/index.html

猜你喜欢

转载自blog.csdn.net/weixin_43876186/article/details/109200014