目录
1. Elasticsearch之常用DSL语句
1.1 操作索引
1.2 文档操作
1.3 DSL查询
1.4 搜索结果处理
1.5 数据聚合
mapping是对索引库中文档的约束,常见的mapping属性包括:
- type:字段数据类型,常见的简单类型有:
- 字符串:text(可分词的文本)、keyword(精确值,例如:品牌、国家、ip地址)
- 数值:long、integer、short、byte、double、float、
- 布尔:boolean
- 日期:date
- 对象:object
- index:是否创建索引,默认为true
- analyzer:使用哪种分词器
创建索引
PUT /goods
{
"mappings": {
"properties": {
"brandName": {
"type": "keyword"
},
"categoryName": {
"type": "keyword"
},
"createTime": {
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss"
},
"id": {
"type": "keyword"
},
"price": {
"type": "double"
},
"saleNum": {
"type": "integer"
},
"status": {
"type": "integer"
},
"stock": {
"type": "integer"
},
"title": {
"type": "text",
"analyzer": "ik_max_word",
}
}
}
}
查询索引
GET /goods
修改索引库
倒排索引结构虽然不复杂,但是一旦数据结构改变(比如改变了分词器),就需要重新创建倒排索引,这简直是灾难。因此索引库一旦创建,无法修改mapping。
虽然无法修改mapping中已有的字段,但是却允许添加新的字段到mapping中,因为不会对倒排索引产生影响。
PUT /索引库名/_mapping
{
"properties": {
"新字段名":{
"type": "integer"
}
}
}
删除索引库
DELETE /goods
新增文档
POST /goods/_doc/1
{
"id": 1,
"brandName": "Apple",
"categoryName": "手机",
"createTime": "2023-12-26 20:00:00",
"price": 8000,
"saleNum": 100,
"status": 0,
"stock": 100,
"title": "Apple iPhone 15 Pro 256GB 远峰蓝色 支持移动联通电信5G 双卡双待手机"
}
POST /goods/_doc/2
{
"id": 2,
"brandName": "Huawei",
"categoryName": "手机",
"createTime": "2023-12-26 20:00:00",
"price": 7000,
"saleNum": 400,
"status": 0,
"stock": 200,
"title": "华为 HUAWEI Mate 60 Pro 智能手机 鸿蒙系统卫星通话昆仑玻璃"
}
查询文档
GET /goods/_doc/1
//批量获取
GET goods/_doc/_mget
{
"ids":["1","2"]
}
删除文档
DELETE /goods/_doc/1
修改文档
全量修改是覆盖原来的文档,其本质是:
注意:如果根据id删除时,id不存在,第二步的新增也会执行,也就从修改变成了新增操作了。
PUT /{索引库名}/_doc/文档id
{
"字段1": "值1",
"字段2": "值2",
// ... 略
}
增量修改是只修改指定id匹配的文档中的部分字段。
POST /{索引库名}/_update/文档id
{
"doc": {
"字段名": "新的值",
}
}
查询所有
GET /goods/_search
{
"query": {
"match_all": {}
}
}
全文检索
//单字段查询
GET /goods/_search
{
"query": {
"match": {
"title": "手机"
}
}
}
//多字段查询
GET /goods/_search
{
"query": {
"multi_match": {
"query": "手机",
"fields": ["title"]
}
}
}
精准查询
精确查询一般是查找keyword、数值、日期、boolean等类型字段。所以不会对搜索条件分词。常见的有:
- term:根据词条精确值查询
- range:根据值的范围查询
term查询的字段是不分词的字段,因此查询的条件也必须是不分词的词条。查询时,用户输入的内容跟自动值完全匹配时才认为符合条件。如果用户输入的内容过多,反而搜索不到数据。
GET /goods/_search
{
"query": {
"term": {
"categoryName": {
"value": "手机"
}
}
}
}
//匹配多个term
GET /goods/_search
{
"query": {
"terms": {
"categoryName": [
"手机",
"电脑"
]
}
}
}
范围查询,一般应用在对数值类型做范围过滤的时候。比如做价格范围过滤。
GET /goods/_search
{
"query": {
"range": {
"price": {
"gte": 7500,
"lte": 9000
}
}
}
}
复合查询
- must:必须匹配的条件,可以理解为“与”
- should:选择性匹配的条件,可以理解为“或”
- must_not:必须不匹配的条件,不参与打分
- filter:必须匹配的条件,不参与打分
POST goods/_search
{
"query": {
"bool": {
"must": [
{
"term": {
"brandName": {
"value": "Apple"
}
}}
],
"should": [
{
"term": {
"categoryName": {
"value": "手机"
}
}}
],
"filter": [
{
"range": {
"stock": {
"gt": 0
}
}
}
]
}
}
}
普通字段排序
GET /goods/_search
{
"query": {
"match_all": {}
},
"sort": [
{
"stock": "desc" //asc升序
}
]
}
分页
elasticsearch中通过修改from、size参数来控制要返回的分页结果:
- from:从第几个文档开始
- size:总共查询几个文档
GET /goods/_search
{
"query": {
"match_all": {}
},
"from": 0,
"size": 1
}
高亮显示
POST goods/_search
{
"query": {
"match": {
"title": "手机"
}
},
"highlight": {
"fields": {
"title": {
"pre_tags": [
""
],
"post_tags": [
""
]
}
}
}
}
聚合常见的有三类:
- 桶(Bucket)聚合:用来对文档做分组
- TermAggregation:按照文档字段值分组,例如按照品牌值分组、按照国家分组
- Date Histogram:按照日期阶梯分组,例如一周为一组,或者一月为一组
- 度量(Metric)聚合:用以计算一些值,比如:最大值、最小值、平均值等
- Avg:求平均值
- Max:求最大值
- Min:求最小值
- Stats:同时求max、min、avg、sum等
- 管道(pipeline)聚合:其它聚合的结果为基础做聚合
统计所有数据中的品牌有几种,按照品牌对数据分组。
GET /goods/_search
{
"size": 0, //设置size为0,结果中不包含文档,只包含聚合结果
"aggs": { // 定义聚合
"brandAgg": { //给聚合起个名字
"terms": { // 聚合的类型,按照品牌值聚合,所以选择term
"field": "brandName", // 参与聚合的字段
"size": 20 // 希望获取的聚合结果数量
}
}
}
}
对于每个品牌的聚合限定聚合范围,并且根据Bucket内的文档数量进行升序排序
GET /goods/_search
{
"query": {
"range": {
"stock": {
"gte": 10
}
}
},
"size": 0, //设置size为0,结果中不包含文档,只包含聚合结果
"aggs": { // 定义聚合
"brandAgg": { //给聚合起个名字
"terms": { // 聚合的类型,按照品牌值聚合,所以选择term
"field": "brandName", // 参与聚合的字段
"size": 20, // 希望获取的聚合结果数量
"order": {
"_count": "asc"
}
}
}
}
}
按照品牌分组,形成了一个个桶。对桶内的数据做运算,获取每个品牌的stock的min、max、avg等值。
GET /goods/_search
{
"query": {
"range": {
"stock": {
"gte": 10
}
}
},
"size": 0,
"aggs": {
"brandAgg": {
"terms": {
"field": "brandName",
"size": 20,
"order": {
"_count": "asc"
}
},
"aggs": {
"stock_status": {
"stats": {
"field": "stock"
}
}
}
}
}
}