全文检索Elasticsearch
1. 相关特点:
- 分布式,无需人工搭建集群(solr需要人为配置,使用zookeeper作为注册中心)
- Restful风格,一切API都遵循Rest原则,容易上手
- 近实时搜索,数据更新在ElasticSearch中几乎是完全同步的。
2. 操作索引
- 基本概念:Elasticsearch是基于Lucene的全文检索库,本质也是存储数据,很多概念与MySql类似的。
-
// 对比关系
索引集(indices)------------------------------------------------Databases 数据库 类型(type)---------------------------------------------Table 数据表 文档(Document)-----------------------------Row 行 字段(Field)----------------------Columns列 - 相关解释:
-
- 类型(type):一个索引库下可以有不同类型的索引,比如商品类型、订单类型,其数据格式不同。不过这回导致索引库混乱,因此未来版本会移除这个概念。
- 映射配置(mappings):字段的数据类型、属性、是否索引、是否存储等特性。
- 分片(shard):数据拆分后的各个部分。
- 副本(replica):每个分片的复制。
-
注意:Elasticsearch本身就是分布式的,因此即使你只有一个节点,Elasticsearch默认也会对你的数据进行分片和副本操作,当你向集群添加数据时,数据也会在新加入的节点中进行平衡。
a、创建索引:
- 请求方式:PUT
- 请求路径:ip地址:端口号/索引库名(下文相关 HTTP请求路径 省略)
- 请求参数:json格式
- 例子:
1234567
{
// settings: 索引库的设置。
"settings"
: {
"number_of_shards"
: 3,
// 分片数量
"number_of_replicas"
: 2
// 副本数量
}
}
b、删除索引
- 请求方式:DELETE
- 请求路径:/索引库名
c、查询索引
- 请求方式:GET
- 请求路径:/索引库名
d、创建映射字段
- 请求方式:PUT
- 请求路径:/索引库名/_mapping/类型名称
- 请求参数:json格式
- 例子:
12345678910
{
"properties"
: {
"字段名"
: {
"type"
:
"类型"
,
"index"
:
true
,
"store"
:
true
,
"analyzer"
:
"分词器"
// 分词器
}
}
}
- 例子:
- 相关解释
- 类型名称:就是type的概念,类似于数据库中的不同表
- 字段名:任意写,可以指定许多属性,例如
- type类型,可以是String类型(text【可分词】、keyword【不可分词】)、long、short、date、integer、object等。
-
注意:如果存的是对象,比如:{girl: {name:"rose",age:21}} 会被处理成两个字段:girl.name和girl.age
-
- index:是否索引,默认为true。如果索引,则可以用来搜索。
- store:是否存储,默认为false。在Elasticsearch中,即便store设为false,也可以搜索到结果(原因:Elasticsearch在创建文档搜索时,会将文档中的原始数据备份,保存到一个叫做_source的属性中。而且我们可以通过过滤_source来选择那些需要显示,那些不显示。
3. 新增数据
- 随机生成id
- 请求方式:POST
- 请求路径:/索引库名/类型名称
- 请求参数: { "key": "value" }
- 自定义id
-
1234
POST /索引库名/类型名称/id值
{
...
}
- 智能判断:
- solr:新增数据时,只能使用提前配置好映射属性的字段,否则会报错。
- Elasticsearch:不需要给索引库设置任何mapping映射,它也可以根据你输入的数据来判断类型,动态添加数据映射。(如果存储的是String类型数据,ES无智能判断,它会存入两个字段。例如:存入一个name字段,智能形成两个字段 name: text类型 name.keyword: keyword类型)
4. 修改数据:
- 请求方式: PUT
- 请求路径:/索引库名/类型名称/id值
- 注意:修改必须指定id。id对应的文档存在,则修改;id对应文档不存在,则新增。
5. 查询
- 基本查询:
1234567891011121314151617181920
GET /索引库名/_search
{
"query"
: {
"查询类型"
: {
"查询条件"
:
"查询条件值"
}
}
}
例子: GET /article/_search
{
"query"
: {
"match"
: {
"title"
: {
"query"
:
"广州上海"
,
"operator"
:
"and"
}
}
}
}
- 查询类型:
- 查询所有(match_all)【全文检索】
- 多字段查询(multi_match)
-
123456789
GET /索引库名/_search
{
"query"
: {
"multi_match"
: {
"query"
:
"查询内容"
,
"fields"
: [
"查询字段1"
,
"查询字段2"
]
}
}
}
- 词条匹配(term):查询被用于精确值匹配,这些精确值可能是数字、时间、布尔或者那些未分词的字符串。推荐除了text以外的类型用term,减少分词带来的消耗,例
12345678
GET /索引库名/_search
{
"query"
: {
"term"
: {
"查询字段"
:
"查询内容"
}
}
}
- 结果过滤:{ "_source" : [ "过滤字段1" , "过滤字段2" ] }。
123456
{
"_source"
: {
# "includes": "过滤字段" # 和上面作用一样
"excludes"
:
"排除过滤字段"
}
}
- 查询类型:
- 高级查询
- 模糊查询(fuzzy)
- 范围查询(range)
1234567891011
GET /索引库名/_search
{
"query"
: {
"range"
: {
"查询字段"
: {
"gte"
: 数值, # 大于,可省略
"lte"
: 数值 # 小于,可省略
}
}
}
}
- 布尔查询和过滤
12345678910111213141516171819
GET /索引库名/_search
{
"query"
: {
"bool"
: {
"must"
: [
{
"match"
: {
"查询字段"
:
"查询内容"
}}
],
"filter"
: {
"range"
: {
"过滤字段"
: {
"gte"
: 数值
}
}
}
}
}
}
- 排序
1234567
"sort"
: [
{
"排序字段"
: {
"order"
:
"desc"
# 降序排序
}
}
]
- 分页: "from" : 数值 "size" : 数值
6. 聚合aggregations:实现对数据的统计、分析
- 基本概念:包括多种类型,最常见的两种,一个叫 桶(bucket),一个叫 度量(metrics)
- 桶:作用:是按照某种方式对数据进行分组,每一组数据在es中称为一个桶(组)。
- Terms Aggregation:根据词条内容分组,词条内容完全匹配的为一组
- Range Aggregation:数值和日期的范围分组,指定开始和结束,然后按段分组
- Histogram Aggregation:根据数值阶梯(Inteval)分组
- Date Aggregation:根据日期阶梯分组,例如:给定阶梯为周,会自动每周分为一组
-
12345678910
GET /索引库名/_search
{
"aggs"
: {
"桶分组名称"
: {
"桶分组方式"
: {
"field"
:
"分桶字段"
}
}
}
}
- 度量:分组完以后,一般会对组中的数据进行聚合运算,例如:求平均值、最大、最小、求和等,这些在es中称为度量
- Avg Aggregation:求平均值
- Max Aggregation:求最大值
- Min Aggregation:求最小值
- Percentiles Aggregation:求百分比
- Stats Aggregation:同时返回avg、max、min、sum、count等
- Sum Aggregation:求和
- Top hits Aggregation:求前几
- Value Count Aggregation:求总数
-
12345678910111213141516171819202122232425262728
GET /索引库名/_search
{
"aggs"
: {
"度量名称"
: {
"度量运算"
: {
"field"
:
"运算字段"
}
}
}
}
例子:{
"size"
: 0,
"aggs"
: {
"popular_brand"
: {
"terms"
: {
"field"
:
"make"
},
"aggs"
: {
"price_avg"
: {
"avg"
: {
"field"
:
"price"
}
}
}
}
}
}
- 桶:作用:是按照某种方式对数据进行分组,每一组数据在es中称为一个桶(组)。