在ES中一个文档是一个可被索引的基础信息单元,也就是一条数据
比如:你可以拥有某一个客户的文档,某一个产品的一个文档,当然,也可以拥有某个订单的一个文档。文档以JSON(Javascript Object Notation)格式来表示,而JSON是一个到处存在的互联网数据交互格式。
在一个index/type里面,你可以存储任意多的文档。
- POST users/_doc
- {
- "user" : "Mike",
- "post_date" : "2019-04-15T14:12:12",
- "message" : "trying out Kibana"
- }
- PUT users/_doc/1?op_type=create
- {
- "user" : "Jack",
- "post_date" : "2019-05-15T14:12:12",
- "message" : "trying out Elasticsearch"
- }
GET users/_doc/1
- POST users/_doc/1
- {
- "user": "Lucy"
- }
GET users/_doc/1
在原文档上增加字段
- POST users/_update/1/
- {
- "doc":{
- "post_date" : "2019-05-15T14:12:12",
- "message" : "trying out Elasticsearch"
- }
- }
再次查看结果
DELETE users/_doc/1
条件删除
- POST users/_delete_by_query
- {
- "query":{
- "match": {
- "user": "Mike"
- }
- }
- }
相当于是数据表的字段,对文档数据根据不同属性进行的分类标识。
mapping是处理数据的方式和规则方面做一些限制,如:某个字段的数据类型、默认值、分析器、是否被索引等等。这些都是映射里面可以设置的,其它就是处理ES里面数据的一些使用规则设置也叫做映射,按着最优规则处理数据对性能提高很大,因此才需要建立映射,并且需要思考如何建立映射才能对性能更好。
- PUT /student
-
- PUT /student/_mapping
- {
- "properties": {
- "name":{
- "type": "text",
- "index": true
- },
- "sex":{
- "type": "text",
- "index": true
- },
- "age":{
- "type": "long",
- "index": true
- }
- }
- }
映射数据说明:
l字段名:任意填写,下面指定许多属性,例如:title、subtitle、images、price
ltype:类型,Elasticsearch中支持的数据类型非常丰富,说几个关键的:
nString类型,又分两种:
text:可分词
keyword:不可分词,数据会作为完整字段进行匹配
nNumerical:数值类型,分两类
基本数据类型:long、integer、short、byte、double、float、half_float
浮点数的高精度类型:scaled_float
nDate:日期类型
nArray:数组类型
nObject:对象
lindex:是否索引,默认为true,也就是说你不进行任何配置,所有字段都会被索引。
true:字段会被索引,则可以用来进行搜索
false:字段不会被索引,不能用来搜索
lstore:是否将数据进行独立存储,默认为false
原始的文本会存储在_source里面,默认情况下其他提取出来的字段都不是独立存储的,是从_source里面提取出来的。当然你也可以独立的存储某个字段,只要设置"store": true即可,获取独立存储的字段要比从_source中解析快得多,但是也会占用更多的空间,所以要根据实际业务需求来设置。
lanalyzer:分词器,这里的ik_max_word即使用ik分词器。
GET /student/_mapping
- PUT /student1
- {
- "settings": {},
- "mappings": {
- "properties": {
- "name":{
- "type": "text",
- "index": true
-
- },
- "sex":{
- "type": "text",
- "index": false
- },
- "age":{
- "type": "long",
- "index": false
- }
- }
- }
- }
Elasticsearch提供了基于JSON提供完整的查询DSL来定义查询
定义数据 :
- POST /student/_doc/1001
- {
- "name":"zhangsan",
- "nickname":"zhangsan",
- "sex":"男",
- "age":30
- }
- POST /student/_doc/1002
- {
- "name":"lisi",
- "nickname":"lisi",
- "sex":"男",
- "age":20
- }
- POST /student/_doc/1003
- {
- "name":"wangwu",
- "nickname":"wangwu",
- "sex":"女",
- "age":40
- }
- POST /student/_doc/1004
- {
- "name":"zhangsan1",
- "nickname":"zhangsan1",
- "sex":"女",
- "age":50
- }
- POST /student/_doc/1005
- {
- "name":"zhangsan2",
- "nickname":"zhangsan2",
- "sex":"女",
- "age":30
- }
term查询,精确的关键词匹配查询,不对查询条件进行分词。
- GET /student/_search
- {
- "query":{
- "match_all": {}
- }
- }
- GET /student/_search
- {
- "query": {
- "match": {
- "name": "zhangsan"
- }
- }
- }
- GET /student/_search
- {
- "query": {
- "multi_match": {
- "query": "zhangsan",
- "fields": ["name", "nickname"]
- }
- }
- }
- GET /student/_search
- {
- "query": {
- "term": {
- "name": {
- "value": "wangwu"
- }
- }
- }
- }
terms 查询和 term 查询一样,但它允许你指定多值进行匹配。
如果这个字段包含了指定值中的任何一个值,那么这个文档满足条件,类似于mysql的in
- GET /student/_search
- {
- "query": {
- "terms": {
- "name": [
- "zhangsan",
- "lisi"
- ]
- }
- }
- }
默认情况下,Elasticsearch在搜索的结果中,会把文档中保存在_source的所有字段都返回。
如果我们只想获取其中的部分字段,我们可以添加_source的过滤
- GET /student/_search
- {
- "_source": "name",
- "query": {
- "terms": {
- "name": [
- "zhangsan"
- ]
- }
- }
- }
我们也可以通过:
includes:来指定想要显示的字段
excludes:来指定不想要显示的字段
- GET /student/_search
- {
- "_source": {
- "includes": ["name","nickname"]
- },
- "query": {
- "terms": {
- "nickname": ["zhangsan"]
- }
- }
- }
- GET /student/_search
- {
- "_source": {
- "excludes": ["name","nickname"]
- },
- "query": {
- "terms": {
- "nickname": ["zhangsan"]
- }
- }
- }
bool把各种其它查询通过must(必须 )、must_not(必须不)、should(应该)的方式进行组合
- GET /student/_search
- {
- "query": {
- "bool": {
- "must": [
- {
- "match": {
- "name": "zhangsan"
- }
- }
- ],
- "must_not": [
- {
- "match": {
- "age": 40
- }
- }
- ],
- "should": [
- {
- "match": {
- "sex": "男"
- }
- }
- ]
- }
- }
- }
range 查询找出那些落在指定区间内的数字或者时间。range查询允许以下字符
操作符 | 说明 |
gt | 大于> |
gte | 大于等于>= |
lt | 小于< |
lte | 小于等于<= |
- GET /student/_search
- {
- "query": {
- "range": {
- "age": {
- "gte": 30,
- "lte": 35
- }
- }
- }
- }
返回包含与搜索字词相似的字词的文档。
编辑距离是将一个术语转换为另一个术语所需的一个字符更改的次数。这些更改可以包括:
- 更改字符(box → fox)
- 删除字符(black → lack)
- 插入字符(sic → sick)
- 转置两个相邻字符(act → cat)
为了找到相似的术语,fuzzy查询会在指定的编辑距离内创建一组搜索词的所有可能的变体或扩展。然后查询返回每个扩展的完全匹配。
通过fuzziness修改编辑距离。一般使用默认值AUTO,根据术语的长度生成编辑距离。
- GET /student/_search
- {
- "query": {
- "fuzzy": {
- "name": {
- "value": "zhangsan"
- }
- }
- }
- }
sort 可以让我们按照不同的字段进行排序,并且通过order指定排序的方式。desc降序,asc升序。
- GET /student/_search
- {
- "query": {
- "fuzzy": {
- "name": "zhangsan"
- }
- },
- "sort": [
- {
- "age": {
- "order" : "desc"
- }
- }
- ]
- }
假定我们想要结合使用 age和 _score进行查询,并且匹配的结果首先按照年龄排序,然后按照相关性得分排序
- GET /student/_search
- {
- "query": {
- "fuzzy": {
- "name": "zhangsan"
- }
- },
- "sort": [
- {
- "age": {
- "order" : "desc"
- }
- },
- {
- "_score": {
- "order": "desc"
- }
- }
- ]
- }
在进行关键字搜索时,搜索出的内容中的关键字会显示不同的颜色,称之为高亮。
在Bing搜索"大数据"
Elasticsearch可以对查询内容中的关键字部分,进行标签和样式(高亮)的设置。
在使用match查询的同时,加上一个highlight属性:
lpre_tags:前置标签
lpost_tags:后置标签
lfields:需要高亮的字段
title:这里声明title字段需要高亮,后面可以为这个字段设置特有配置,也可以空
- GET /student/_search
- {
- "query": {
- "match": {
- "name": "zhangsan"
- }
- },
- "highlight": {
- "pre_tags": "",
- "post_tags": "",
- "fields": {
- "name": {}
- }
- }
- }
from:当前页的起始索引,默认从0开始。 from = (pageNum - 1) * size
size:每页显示多少条
- GET /student/_search
- {
- "query": {
- "match_all": {}
- },
- "sort": [
- {
- "age": {
- "order": "desc"
- }
- }
- ],
- "from": 0,
- "size": 2
- }
聚合允许使用者对es文档进行统计分析,类似与关系型数据库中的group by,当然还有很多其他的聚合,例如取最大值、平均值等等。
对某个字段取最大值max
- GET /student/_search
- {
- "aggs":{
- "max_age":{
- "max":{"field":"age"}
- }
- },
- "size":0
- }
桶聚和相当于sql中的group by语句
terms聚合,分组统计
- GET /student/_search
- {
- "aggs":{
- "age_groupby":{
- "terms":{"field":"age"}
- }
- },
- "size":0
- }