Elasticsearch系列——使用kibana或postman操作Elasticsearch的常用命令(二)

作者专注于Java、架构、Linux、小程序、爬虫、自动化等技术。 工作期间含泪整理出一些资料,微信搜索【程序员高手之路】,回复 【java】【黑客】【爬虫】【小程序】【面试】等关键字免费获取资料。 

目录

前言

五、高级查询

1. 精准查询(短语搜索)

1.1 简单的短语搜索

1.2 与slop结合

1.3 rescore(重打分)

2. 多字段匹配查询

3. 语法查询

4. 字段查询(结构化查询)

5. 分页查询

6. 范围查询

6.1 数字类型

6.2 日期类型

7. 过滤查询

8. 分数查询

9. 布尔查询

9.1 should查询

9.2 must查询

9.3 must与filter相结合

9.4 must_not

10. 高亮查询

10.1 默认标签

10.2 指定标签

11 聚合查询

11.1 根据字段类型查询

11.2 查询总体值

11.3 查询最小值

11.4 先分组后计算

12.排序查询

13 scroll查询

14 分词查询

14.1 随便写一个句子进行分词

14.2 自定义分词器


前言

运行系统:windows10

JDK版本:1.8

Elasticsearch版本:5.6.6

插件:kibana、elasticsearch-head

工具:postman

本文介绍高级搜索命令,建议首先参考简单的命令:点击打开链接

五、高级查询

高级查询有很多种,下面介绍常用的几种:

1. 精准查询(短语搜索)

1.1 简单的短语搜索

与简单的查询 点击打开链接 里面的4.3的模糊查询(全文搜索)正好相反,这个是精确匹配

也就是说,只能是“叶良辰”三个字连在一起的才能被搜索出来!

GET /people/_search
{
  "query": {
    "match_phrase": {
      "name": "叶良辰"
    }
  }
}

但是一种情况除外,比如搜索中只有一个汉字,只要name里面包含“辰”这个字就会被查出来:

GET people/man/_search
{
  "query": {
    "match_phrase": {
      "name": "辰"
    }
  }
}

1.2 与slop结合

GET /people/_search
{
  "query": {
    "match_phrase": {
      "name": {
        "query": "张三",
        "slop": 3
      }
    }
  }
}

解读:slop是移动次数,上面案例表示“张”、“三”两个字可以经过最多挪动3次查询到!

例如“张小三”,“三个张”这两个是可以被查到的!

1.3 rescore(重打分)

GET /forum/article/_search
{
  "query": {
    "match": {
      "content": "java spark"
    }
  },
  "rescore":{
    "window_size": 50,
    "query": {
      "rescore_query": {
        "match_phrase": {
          "content": {
            "query": "java spark",
            "slop": 50
          }
        }
      }
    }
  }
}

2. 多字段匹配查询

注意:这样的查询也是模糊查询,会把“叶良辰”拆分成“叶”、“良”和“辰”进行查询;并且在多个字段里查询!

GET /people/_search
{
  "query": {
    "multi_match": {
      "query": "叶良辰",
      "fields": ["name","desc"]
    }
  }
}

3. 语法查询

注意:“叶良辰 AND 风”会先把“叶良辰”拆分成“叶”、“良”和“辰”,然后后面必须有“风”;

GET /people/_search
{
  "query": {
    "query_string": {
      "query": "叶良辰 AND 风"
    }
  }
}

下面的语法匹配,自行脑补

GET /people/_search
{
  "query": {
    "query_string": {
      "query": "(叶良辰 AND 火) OR (赵日天 AND 风)",
      "fields": ["name","desc"]
    }
  }
}

4. 字段查询(结构化查询)

下面的是精准查询:

GET /people/_search
{
  "query": {
    "term": {
      "name": "叶良辰"
    }
  }
}

5. 分页查询

GET /people/_search
{
  "query": {
    "match_all": {}
  },
  "from": 1,
  "size": 1
}

6. 范围查询

6.1 数字类型

GET /people/_search
{
  "query": {
    "range": {
      "age": {
        "gt": 16,
        "lte": 30
      }
    }
  }
}

6.2 日期类型

GET /people/_search
{
  "query": {
    "range": {
      "birthday": {
        "gte": "2013-01-01",
        "lte": "now"
      }
    }
  }
}

日期类型可以用下面的语法来查询:

GET book/_search
{
  "query": {
    "constant_score": {
      "filter": {
        "range": {
          "date": {
            "gt": "now-1M"
          }
        }
      },
      "boost": 1.2
    }
  }
}

其中,"gt": "now-1M"表示从今天开始,往前推一个月!

7. 过滤查询

两种方式:一种是通过constant_score,也就是恒定的分数,后面boost分数默认为1.2:

POST /people/man/_search
{
  "query": {
    "constant_score": {
      "filter": {
        "range": {
          "age": {
            "gte": 20,
            "lte": 30
          }
        }
      },
      "boost": 1.2
    }
  }
}

另一种是通过bool:

POST /people/_search
{
  "query": {
    "bool": {
      "filter": {
        "term": {
          "age": 18
        }
      }
    }
  }
}

8. 分数查询

POST /people/_search
{
  "query": {
    "constant_score": {
      "filter": {
        "match": {
          "name": "叶良辰"
        }
      },
      "boost": 2
    }
  }
}

9. 布尔查询

注意:条件可以是数组[ ],也可以是单个条件{ }

9.1 should查询

注意:should相当于 或 ,里面的match也是模糊匹配

POST /people/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "match": {
            "name": "叶良辰"
          }
        },
        {
          "match": {
            "desc": "赵日天"
          }
        }
      ]
    }
  }
}

9.2 must查询

注意:两个条件都要满足,并且这里也会把must里面的“叶良辰”拆分成“叶”、“良”和“辰”进行查询;“赵日天”拆分成“赵”、“日”、和“天”!

POST /people/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "name": "叶良辰"
          }
        },
        {
          "match": {
            "desc": "赵日天"
          }
        }
      ]
    }
  }
}

9.3 must与filter相结合

这里也会把must里面的“叶良辰”拆分成“叶”、“良”和“辰”进行查询

POST /people/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "name": "叶良辰"
          }
        },
        {
          "match": {
            "desc": "赵日天"
          }
        }
      ],
      "filter": [
        {
          "term": {
            "age": 18
          }
        }
      ]
    }
  }
}

9.4 must_not

注意:下面语句是精准匹配

POST /people/_search
{
  "query": {
    "bool": {
      "must_not": {
        "term": {
          "name": "叶良辰"
        }
      }
    }
  }
}

10. 高亮查询

10.1 默认标签<em>

GET people/_search
{
  "query": {
    "match": {
      "name": "叶良辰"
    }
  },
  "highlight": {
    "fields": {
      "name": {}
    }
  }
} 

查询结果中会有<em>标签标识,可以结合上面的查询方式查看

10.2 指定标签

设置pre_tagspost_tags的属性

GET people/_search
{
  "query": {
    "match": {
      "name": "叶良辰"
    }
  },
  "highlight": {
    "pre_tags": ["<b>"], 
    "post_tags": ["</b>"], 
    "fields": {
      "name": {}
    }
  }
} 

11 聚合查询

11.1 根据字段类型查询

GET /people/man/_search
{
  "size": 0, 
  "aggs": {
    "group_by_age": {
      "terms": {
        "field": "age"
      }
    }
  }
}

11.2 查询总体值

POST /people/_search
{
  "aggs": {
    "grads_age": {
      "stats": {
        "field": "age"
      }
    }
  }
}

11.3 查询最小值

POST /people/_search
{
  "aggs": {
    "grads_age": {
      "min": {
        "field": "age"
      }
    }
  }
}

11.4 先分组后计算

根据国家分组,然后计算年龄平均值:

GET /people/man/_search
{
  "size": 0, 
  "aggs": {
    "group_by_age": {
      "terms": {
        "field": "country"
      },
      "aggs": {
        "avg_age": {
          "avg": {
            "field": "age"
          }
        }
      }
    }
  }
}

执行之后,发现报错:

解决:上面的reason里面说的很清楚,将fielddata设置为true就行了:

POST /people/_mapping/man
{
  "properties": {
    "country": {
      "type": "text",
      "fielddata": true
    }
  }
}

然后重新执行命令,得到下面的结果:

12.排序查询

排序查询通常没有排到我们想要的结果,因为字段分词后,有很多单词,再排序跟我们想要的结果又出入

解决办法:把需要排序的字段建立两次索引,一个排序,另一个不排序。

如下面的案例:把title.raw的fielddata设置为true,是排序的;而title的fielddata默认是false,可以用来搜索

index: true 是在title.raw建立索引可以被搜索到,

fielddata: true是让其可以排序

PUT /blog
{
  "mappings": {
    "article": {
      "properties": {
        "auther": {
          "type": "text"
        },
        "title": {
          "type": "text",
          "fields": {
            "raw":{
              "type": "text",
              "index": true,
              "fielddata": true
            }
          }
        },
        "content":{
          "type": "text",
          "analyzer": "english"
        },
        "publishdate": {
          "type": "date"
        }
      }
    }
  }
} 

对应的搜索命令:

GET /blog/article/_search
{
  "query": {
    "match_all": {}
  },
  "sort": [
    {
      "title.raw": {
        "order": "desc"
      }
    }
  ]
}

13 scroll查询

当搜索量比较大的时候,我们在短时间内不可能一次性搜索完然后展示出来

这个时候,可以使用scroll进行搜索

比如下面的案例,可以先搜索3条数据,然后结果中会有一个_scroll_id,下次搜索就可以直接用这个_scroll_id进行搜索了:

step1 搜索:

GET test_index/test_type/_search?scroll=1m
{
  "query": {
    "match_all": {}
  },
  "sort": "_doc", 
  "size": 3
}

step2 复制结果中的_scroll_id:

step3 把scroll_id粘贴到下面的命令中再次搜索

GET _search/scroll
{
  "scroll": "1m",
  "scroll_id": "DnF1ZXJ5VGhlbkZldGNoBQAAAAAAAAA6FnZPSl9sbVR4UVVDU1NLb2wxVXJlbWcAAAAAAAAAPhZ2T0pfbG1UeFFVQ1NTS29sMVVyZW1nAAAAAAAAADsWdk9KX2xtVHhRVUNTU0tvbDFVcmVtZwAAAAAAAAA8FnZPSl9sbVR4UVVDU1NLb2wxVXJlbWcAAAAAAAAAPRZ2T0pfbG1UeFFVQ1NTS29sMVVyZW1n"
}

后面的操作重复step3就OK了!

14 分词查询

14.1 随便写一个句子进行分词

GET _analyze
{
  "analyzer": "standard",
  "text": "this is a test for analyzer"
}

14.2 自定义分词器

char_filter是映射字符过滤器,该例子是把&符号转化为and

filter中使用停止词过滤器,移除自定义的停止词列表中包含的词

PUT /my_index
{
  "settings": {
    "analysis": {
      "char_filter": {
        "&_to_and": {
          "type": "mapping",
          "mappings": ["&=> and "]
        }
      },
      "filter": {
        "my_stopwords": {
          "type": "stop",
          "stopwords": ["the","a"]
        }
      },
      "analyzer": {
        "my_analyzer": {
          "type": "custom",
          "char_filter": ["html_strip","&_to_and"],
          "tokenizer": "standard",
          "filter": ["lowercase","my_stopwords"]
        }
      }
    }
  }
} 

然后就可以使用下列命令来测试该分词器:

GET my_index/_analyze
{
  "analyzer": "my_analyzer",
  "text": "Tom&Jerry are the best friends"
} 

结果:大写转为了小写;&转为了and;the已经被去掉

OK,GAME OVER! 

更多内容,请关注公众号:程序员高手之路

在公众号回复:es基础   即可免费获取elasticsearch视频教程(未加密)!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前方一片光明

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值