ES

Jingxc大约 7 分钟java后端java后端Elasticsearch

ES

ES(Elasticsearch)Elasticsearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java语言开发的,并作为Apache许可条款下的开放源码发布,是一种流行的企业级搜索引擎。Elasticsearch用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便 。 其实记住是一个分布式全文搜索引擎,重点是全文搜索。

全文搜索:​这里解释一下全文索引比如用户要搜索一个文章,以Java为关键字进行搜索,不管是书名中还是文章的标题,文章的作者名字,文章的摘要,只要是包含java关键字就会作为查询结果返回给用户查看,这就使用了全文搜索技术。 搜索的条件不再是仅用于对某一个字段进行比对与查找,而是在一条数据中使用搜索条件去比对表中更多的字段,只要能匹配上就作为查询结果,而ES技术就是一种可以实现上述效果的技术。

关键字

  • 索引<Index> 一组相似文档的集合

一个索引就是一个拥有几分相似特征的文档的集合。比如说,你可以有一个商品数据的索引,一个订单数据的索引,还有一个用户数据的索引。一个索引由一个名字来标识(必须全部是小写字母的),并且当我们要对这个索引中的文档进行索引、搜索、更新和删除的时候,都要使用到这个名字。

  • 映射<Mapping> 用来定义索引存储文档的结构:字段、类型等

映射是定义一个文档和它所包含的字段如何被存储和索引的过程。在默认配置下,ES可以根据插入的数据自动地创建mapping,也可以手动创建mapping。 mapping中主要包括字段名、字段类型等

  • 文档<Document> 索引中一条记录,可以被索引的最小单元

文档是索引中存储的一条条数据。一条文档是一个可被索引的最小单元。ES中的文档采用了轻量级的JSON格式数据来表示。

  • 分片<shards>

Elasticsearch提供了将索引划分成多份的能力,这些份就叫做分片。当你创建一个索引的时候,你可以指定你想要的分片的数量。每个分片本身也是一个功能完善并且独立的“索引”,这个“索引”可以被放置 到集群中的任何节点上。

  • 复制<replicas>

Index的分片中一份或多份副本。

关键字对比


ES对比ES对比
must相当于MySql中的andterm完全匹配
should相当于MySql中的orfuzzy误拼写查询
must_not不等于range范围查询
gt大于wildcard模糊查询
git大于等于exists排除null
lt小于match_phrase短语匹配
lte小于等于match_phrase和match区别match是分词匹配(将输入的词进行分词),match_phrase是短语匹配(输入文本进行查找)
match分词查询

ES存储类型

文本类型 - text

在Elasticsearch 5.4 版本开始, text取代了需要分词的string, 当一个字段需要用于全文搜索(会被分词), 比如产品名称、产品描述信息, 就应该使用text类型.

text的内容会被分词, 可以设置是否需要存储: “index”: “true|false” 。text类型的字段不能用于排序, 也很少用于聚合.

PUT website
{
	"mappings": {
        "blog": {
            "properties": {
        		"summary": {"type": "text", "index": "true"}
            }
        }
    }
}

关键字类型 - keyword


在Elasticsearch 5.4 版本开始, keyword取代了不需要分词的string.当一个字段需要按照精确值进行过滤、排序、聚合等操作时, 就应该使用keyword类型.

keyword的内容不会被分词, 可以设置是否需要存储: “index”: “true|false”.

PUT website
{
	"mappings": {
        "blog": {
            "properties": {
        		"tags": {"type": "keyword", "index": "true"}
            }
        }
    }
}

数字类型-8种


类型说明
byte有符号的8位整数, 范围: [-128 ~ 127]
short有符号的16位整数, 范围: [-32768 ~ 32767]
integer有符号的32位整数, 范围: [−231 ~ 231-1]
long有符号的64位整数, 范围: [−263 ~ 263-1]
float32位单精度浮点数
double64位双精度浮点数
half_float16位半精度IEEE 754浮点类型
scaled_float缩放类型的的浮点数, 比如price字段只需精确到分, 57.34缩放因子为100, 存储结果为5734

注意

使用注意事项:

尽可能选择范围小的数据类型, 字段的长度越短, 索引和搜索的效率越高;优先考虑使用带缩放因子的浮点类型.

PUT shop
{
    "mappings": {
        "book": {
            "properties": {
                "name": {"type": "text"},
                "quantity": {"type": "integer"},  // integer类型
                "price": {
                    "type": "scaled_float",       // scaled_float类型
                    "scaling_factor": 100
                }
            }
        }
    }
}

日期类型 - date


JSON没有日期数据类型, 所以在ES中, 日期可以是:包含格式化日期的字符串, “2018-10-01”, 或"2018/10/01 12:10:30"

代表时间毫秒数的长整型数字。代表时间秒数的整数.

如果时区未指定, 日期将被转换为UTC格式, 但存储的却是长整型的毫秒值.

可以自定义日期格式, 若未指定, 则使用默认格式: strict_date_optional_time||epoch_millis

# 添加映射
PUT website
  {
  "mappings": {
    "blog": {
      "properties": {
        "pub_date": {"type": "date"}   # 日期类型
      }
    }
  }
}
# 添加数据
PUT website/blog/11
{ "pub_date": "2018-10-10" }

PUT website/blog/12
{ "pub_date": "2018-10-10T12:00:00Z" }	# Solr中默认使用的日期格式

PUT website/blog/13
{ "pub_date": "1589584930103" }			# 时间的毫秒值

多种日期格式:

多个格式使用双竖线||分隔, 每个格式都会被依次尝试, 直到找到匹配的.第一个格式用于将时间毫秒值转换为对应格式的字符串.


# 添加映射
PUT website
{
    "mappings": {
        "blog": {
            "properties": {
                "date": {
                    "type": "date",  // 可以接受如下类型的格式
                    "format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
                }
            }
        }
    }
}

布尔类型 - boolean


可以接受表示真、假的字符串或数字:

真值: true, “true”, “on”, “yes”, “1”…

假值: false, “false”, “off”, “no”, “0”, “”(空字符串), 0.0, 0

二进制型 - binary


二进制类型是Base64编码字符串的二进制值, 不以默认的方式存储, 且不能被搜索. 有2个设置项:

  • doc_values: 该字段是否需要存储到磁盘上, 方便以后用来排序、聚合或脚本查询. 接受true和false(默认);

  • store: 该字段的值是否要和_source分开存储、检索, 意思是除了_source中, 是否要单独再存储一份. 接受true或false(默认).

# 添加映射
PUT website
{
    "mappings": {
        "blog": {
            "properties": {
                "blob": {"type": "binary"}   # 二进制
            }
        }
    }
}
# 添加数据
PUT website/blog/1
{
    "title": "Some binary blog",
    "blob": "hED903KSrA084fRiD5JLgY=="
}

注意

注意: Base64编码的二进制值不能嵌入换行符\n, 逗号(0x2c)等符号.

范围类型 - range


range过滤允许我们按照制定范围查找一批数据

复杂数据类型Array


ES中没有专门的数组类型, 直接使用[]定义即可;

数组中所有的值必须是同一种数据类型, 不支持混合数据类型的数组:

① 字符串数组: [“one”, “two”];

② 整数数组: [1, 2];

③ 由数组组成的数组: [1, [2, 3]], 等价于[1, 2, 3];

④ 对象数组: [{“name”: “Tom”, “age”: 20}, {“name”: “Jerry”, “age”: 18}].

注意

动态添加数据时, 数组中第一个值的类型决定整个数组的类型; 不支持混合数组类型, 比如[1, “abc”]; 数组可以包含null值, 空数组[]会被当做missing field —— 没有值的字段.

复杂数据类型Object


JSON文档是分层的: 文档可以包含内部对象, 内部对象也可以包含内部对象.

复杂数据类型嵌套类型 - nested


嵌套类型是对象数据类型的一个特例, 可以让array类型的对象被独立索引和搜索.

专门数据类型IP类型


IP类型的字段用于存储IPv4或IPv6的地址, 本质上是一个长整型字段.

#添加映射
PUT employee
{
    "mappings": {
        "customer": {
            "properties": {
                "ip_addr": { "type": "ip" }
            }
        }
    }
}

#添加数据
PUT employee/customer/1
{ "ip_addr": "192.168.1.1" }

计数数据类型 - token_counttoken_count类型用于统计字符串中的单词数量.


## 添加映射
PUT employee
{
  "mappings": {
    "customer": {
      "properties": {
        "name": {
          "type": "text",
          "fields": {
            "length": {
              "type": "token_count",
              "analyzer": "standard"
            }
          }
        }
      }
    }
  }
}

## 添加数据
PUT employee/customer/1
{ "name": "John Snow" }
PUT employee/customer/2
{ "name": "Tyrion Lannister" }

## 查询数据
GET employee/customer/_search
{
  "query": {
    "term": { "name. length": 2 }
  } 
}
上次编辑于:
贡献者: Jingxc