【ElasticSearch】基本概念与基本语法

1、基本概念

一、Cluster(集群)

es集群对外提供索引和搜索的服务,其包含一个或者多个节点,每一个节点都有统一的集群名称。参考本地集群搭建node

image.png

二、Node(节点)

单独一个Elasticsearch服务器实例称为一个node,node是集群的一部分,每一个node有独立的名称,默认是启动时获取一个UUID做为名称,也能够自行配置。git

三、Shard(分片)

Shard分片也称为primary shard,是单个Lucene索引,因为单台机器的存储容量是有限的,而Elasticsearch索引的数据可能特别大,单台机器没法存储所有数据,就须要将索引中的数据切分为多个shard,分布在多台服务器上存储。利用shard能够很好地进行横向扩展,存储更多数据,让搜索和分析等操做分布到多台服务器上去执行,提高集群总体的吞吐量和性能。建立索引时就应该预估好须要的分片数量,一旦建立则分片数量没法更改。github

四、Replica(复制分片)

replica全称叫replica shard,是索引的副本,彻底拷贝shard的内容,shard与replica的关系能够是一对多,同一个shard能够有一个或多个replica。当集群中有节点宕机了,丢失的shard会由replica补位,保证数据高可用;replica shard也能分担查询请求,提高集群的吞吐量。数据库

五、Index(索引)

es索引,其保存具备相同结构的文档集合,相似于关系型数据库的数据库实例(6.0.0版本type废弃后,索引的概念降低到等同于数据库表的级别)。一个集群里能够定义多个索引json

六、Type(类型)

类型,本来是在索引(Index)内进行的逻辑细分,但后来发现企业研发为了加强可阅读性和可维护性,制订的规范约束,同一个索引下不多还会再使用type进行逻辑拆分(如同一个索引下既有订单数据,又有评论数据),于是在6.0.0版本以后,此定义废弃。segmentfault

七、Document(文档)

Elasticsearch最小的数据存储单元,JSON数据格式,相似于关系型数据库的表记录(一行数据),结构定义多样化,同一个索引下的document,结构尽量相同。api

八、Field type(字段类型)

  • text:被分析索引的字符串类型
  • keyword:不能被分析,只能被精确匹配的字符串类型
  • date:日期类型,能够配合format一块儿使用
  • long:长整型,数字类型
  • integer:整型,数字类型
  • short:短整型,数字类型
  • double:双精度浮点型,数字类型
  • Boolean:布尔型,true、false
  • array:数组类型
  • object:对象类型,json嵌套
  • ip:ip类型
  • geo_point:地理位置类型

九、分词器

ElasticSearch借助各类类型的分词器来对文档内容进行分词处理,以便于建立倒排索引,这是搜索的核心。同时也对搜索内容进行分词处理,用以在倒排索引中索引文档。数组

一、内置分词器

标准分词器(standard analyzer)(默认)
  • 分析过程:字符过滤器->字符处理->分词过滤(分词转换)

说明:首先是字符过滤器过滤掉特殊符号以及量词(the、an、a等),进一步将分词小写处理,服务器

英文分词器(english analyzer)
  • 分析过程:字符过滤器->字符处理->分词过滤(分词转换,词干转化)

说明:首先是字符过滤器过滤掉特殊符号以及量词(the、an、a等),进一步将分词小写处理,再次进行分词转换,例如:eating -> eat,其实它们两是一回事。app

简单分词器(simple analyzer)

先按照空格分词,英文大写转小写。

空格分词器(whitespace analyzer)

先按照空格分词,英文不作大小写处理。

二、外部分词器

中文分词器(ik_maxword)

会将文本作最细粒度的拆分;尽量多的拆分出词语,例如:如南京市长江大桥 --> 南京市/南京/市长/长江大桥/长江/大桥

中文分词器(ik_smart)

会作最粗粒度的拆分;已被分出的词语将不会再次被其它词语占有,如南京市长江大桥 --> 南京市/长江大桥

安装中文分词器
  • 安装方式一
#去GitHub下载与elasticsearch对应版本的分词插件
https://github.com/medcl/elasticsearch-analysis-ik/releases

#进入es的plugins目录建立文件夹
cd /usr/local/elasticsearch-7.8.0/plugins
mkdir analysis-ik

#解压ik分词插件到ik文件夹
unzip elasticsearch-analysis-ik-7.8.0.zip
  • 安装方式二
cd /usr/local/elasticsearch-7.8.0/bin

#执行es自带插件安装命令
./elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.8.0/elasticsearch-analysis-ik-7.8.0.zip

说明:经过以上两种方式之一安装都可,安装好插件重启es服务便可。

十、评分规则

  • TF(token frequency):词频,文档中出现分词的数量,出现次数越多,相关性越强。
  • IDF(inverse document frequency):逆向文档频率,包含分词的文档数量相关,包含分词的文档数量越多则代表相关性越弱。
  • TFNORM(token frequency normalize):词频规格化,根据field长度作归一化,文档内出现频率越高,field越短相关性越强。

2、基本语法

一、准备数据

抱着学习的目的,首先须要ElasticSearch的环境,有了环境之后,咱们还须要初始化一批数据,我们能够借助TMDB(the movie database)数据源来方便咱们练习基本语法。

二、建立索引

  • 非结构化方式建立索引
PUT /employee
{
  "settings": {
    "number_of_shards": 1,
    "number_of_replicas": 1
  }
}
  • 结构化方式建立索引
PUT /movie
{
  "settings": {
    "number_of_shards": 1,
    "number_of_replicas": 1
  },
  "mappings": {
    "properties": {
      "title":{"type": "text","analyzer": "english"},
      "tagline":{"type": "text","analyzer": "english"},
      "release_date":{"type": "date","format": "8yyyy/MM/dd||yyyy/M/dd||yyyy/MM/d||yyyy/M/d"},
      "popularity":{"type": "double"},
      "overview":{"type": "text","analyzer": "english"},
      "cast":{
        "type": "object",
        "properties": {
          "character":{"type":"text","analyzer":"standard"},
          "name":{"type":"text","analyzer":"standard"}
        }
      }
    }
  }
}

说明:以上指定了个别字段使用英文分词器,日期类型指定了format,能够支持解析多种类型的日期字符串格式。

三、删除索引

  • 删除索引
DELETE /employee

四、新增文档

  • 强制指定建立,若已存在,则失败
POST /employee/_create/1
{
  "name":"关二爷",
  "age":31
}
  • (不存在)新增或者(存在)更新文档
PUT /employee/_doc/1
{
  "name":"jayway1",
  "age":30
}

说明:若是文档不存在,则会插入文档,若是文档已存在,则会覆盖原文档。

五、修改文档

  • 指定更新字段更新文档
POST /employee/_update/1
{
  "doc": {
    "name":"jayway2"
  }
}

说明:指定字段更新就只会更新指定的字段,不会去覆盖原文档。

五、删除文档

  • 删除指定文档
DELETE /employee/_doc/1

六、简单查询文档

  • 查询指定文档
GET /employee/_doc/2
  • 查询多条文档
GET /employee/_search
  • 不带条件查询全部记录
GET /employee/_search
{
  "query": {
    "match_all": {}
  }
}
  • 分页查询
GET /employee/_search
{
  "query": {
    "match_all": {}
  },
  "from": 0,
  "size": 20
}
  • 带关键字的条件查询
GET /employee/_search
{
  "query": {
    "match": {
      "name": "关羽"
    }
  }
}
  • 带关键字的条件查询,并排序
GET /employee/_search
{
  "query": {
    "match": {
      "name": "关"
    }
  },
  "sort": [
    {
      "age": {
        "order": "desc"
      }
    }
  ]
}

说明:自主排序后,分数就没有意义了,分数值为null

  • 指定操做符查询
#分词后的and和or的逻辑,match默认使用的是or
GET /movie/_search
{
  "query": {
    "match": {
      "title": "basketball with cartoom aliens"
    }
  }
}

GET /movie/_search
{
  "query": {
    "match": {
      "title": {
        "query": "basketball with cartoom aliens",
        "operator": "and"
      }
    }
  }
}
  • 指定最小词匹配项查询
#最小词匹配项(最小匹配两个词)
GET /movie/_search
{
  "query": {
    "match": {
      "title": {
        "query": "basketball love aliens",
        "operator": "or",
        "minimum_should_match": 2
      }
    }
  }
}
  • 短语查询
#短语查询,将查询内容视做一个短语,不作分词
GET /movie/_search
{
  "query": {
    "match_phrase": {
      "title": "steve zissou"
    }
  }
}
  • 多字段查询
GET /movie/_search
{
  "query": {
    "multi_match": {
      "query": "basketball with cartoom aliens",
      "fields": ["title","overview"]
    }
  }
}

说明:待查询内容分词分别匹配各个字段,每一个字段都有一个评分,取最大的评分。

  • 优化多字段查询
#咱们认为title字段比较重要,人为地去干涉评分的权重,
#以下的含义是:评分放大系数(boost,默认2.2)放大十倍
#tie_breaker:将除最大评分字段之外的其它字段得分乘以此系数累加到最大评分中得到最终得分;综合考虑多个字段得分,而不是一刀切
GET /movie/_search
{
  "explain": true,
  "query": {
    "multi_match": {
      "query": "basketball with cartoom aliens",
      "fields": ["title^10","overview"],
      "tie_breaker": 0.3
    }
  }
}
  • 指定查询类型的查询
#best_fields(最匹配模式):默认的得分方式,取得最高的分数做为对应文档的对应分数
GET /movie/_search
{
  "query": {
    "multi_match": {
      "query": "basketball with cartoom aliens",
      "fields": ["title^10","overview"]
    }
  }
}

#most_fields:考虑绝大多数(全部的),文档的字段得分相加,得到咱们想要的结果
GET /movie/_search
{
  "query": {
    "multi_match": {
      "query": "basketball with cartoom aliens",
      "fields": ["title^10","overview^0.1"],
      "type": "most_fields"
    }
  }
}

#cross_fields:以分词为单位计算栏位的总分,适用于词维度的匹配,分词在各个字段中的得分取最大值,而后累加这些最大得分
GET /movie/_search
{
  "query": {
    "multi_match": {
      "query": "steve job",
      "fields": ["title","overview"],
      "type": "cross_fields"
    }
  }
}
  • query string方式查询
#方便的利用 and or not
GET /movie/_search
{
  "query": {
    "query_string": {
      "fields": ["title"],
      "query": "steve or jobs"
    }
  }
}

七、布尔查询

  • 单条件过滤
GET /movie/_search
{
  "query": {
    "bool": {
      "filter": {
        "term": {"title": "steve"}
      }
    }
  }
}

说明:term关键字查询不会分词,match才会分词

  • 多条件过滤
GET /movie/_search
{
  "query": {
    "bool": {
      "filter": [
        {"term":{"title": "steve"}},
        {"term":{"cast.name": "gaspard"}},
        {"range":{"release_date": {"lte":"2014/01/01"}}},
        {"range":{"popularity": {"gte":"25"}}}
      ]
    }
  }
}
  • 布尔查询
#bool查询
#must:必须都为true
#must not:必须都是false
#should:其中只有一个为true便可
#为true越多则分数越高
GET /movie/_search
{
  "query": {
    "bool": {
      "should": [
        {"match": {"title": "basketball with cartoom aliens"}},
        {"match": {"overview": "basketball with cartoom aliens"}}
      ]
    }
  }
}
  • 带match打分的filter
GET /movie/_search
{
  "query": {
    "bool": {
      "should": [
        {"match":{"title": "life"}}
      ], 
      "filter": [
        {"term":{"title": "steve"}},
        {"term":{"cast.name": "gaspard"}},
        {"range":{"release_date": {"lte":"2014/01/01"}}},
        {"range":{"popularity": {"gte":"25"}}}
      ]
    }
  }
}

说明:match查询负责打分匹配,filter负责过滤,最终返回的文档是有分数的。

  • 多条件过滤加排序
GET /movie/_search
{
  "query": {
    "bool": {
      "filter": [
        {"term":{"title": "steve"}},
        {"term":{"cast.name": "gaspard"}},
        {"range":{"release_date": {"lte":"2014/01/01"}}},
        {"range":{"popularity": {"gte":"25"}}}
      ]
    }
  },
  "sort": [
    {
      "popularity": {
        "order": "desc"
      }
    }
  ]
}

八、自定义得分查询

  • 自定义得分查询
#functionscore,对原始查询获得的分数,进一步进行处理
GET /movie/_search
{
  "query": {
    "function_score": {
      "query": {
        "multi_match": {
          "query": "steve job",
          "fields": ["title","overview"],
          "operator": "or",
          "type": "most_fields"
        }
      },
      "functions": [
        {
          "field_value_factor": {
            "field": "popularity",
            "modifier": "log2p",
            "factor": 10
          }
        },
        {
          "field_value_factor": {
            "field": "popularity",
            "modifier": "log2p",
            "factor": 5
          }
        }
      ],
      "score_mode": "sum",
      "boost_mode": "sum"
    }
  }
}

九、聚合查询

GET /employee/_search
{
  "query": {
    "match": {
      "name": "关"
    }
  },
  "sort": [
    {
      "age": {
        "order": "desc"
      }
    }
  ],
  "aggs": {
    "group_by_age": {
      "terms": {
        "field": "age",
        "size": 10
      }
    }
  }
}

九、查询分析

  • 使用analyze api查看分词状态
GET /movie/_analyze
{
  "field": "name",
  "text": "Eating an apple a day & keeps the doctor away"
}
  • 使用explain查看打分的分析结果
GET /movie/_search
{
  "explain": true,
  "query": {
    "match": {
      "title": "steve"
    }
  }
}
  • explanation
GET /movie/_validate/query?explain
{
  "query": {
    "multi_match": {
      "query": "basketball with cartoom aliens",
      "fields": ["title^10","overview"],
      "type": "best_fields"
    }
  }
}
相关文章
相关标签/搜索