es各种查询(转)
1、 GET /lib/user/_search
: 查询lib索引下的user类型的全部数据
2、 GET /lib/_search
:查询lib索引下的全部类型的数据
3、 GET /_search
:查询全部索引下的数据
精确值查找
- 当进行精确值查找时, 我们会使用 过滤器(filters)
。过滤器很重要,因为它们 执行速度非常快
,不会计算相关度(直接跳过了整个评分阶段)而且很容易被缓存。我们会在本章后面的 过滤器缓存
中讨论过滤器的性能优势,不过现在只要记住:请尽可能多的使用过滤式查询。
term查询
- elasticsearch对这个搜索的词语不做分词,用于精确匹配,比如Id,数值类型的查询。
- 可以用它处理数字(numbers)、布尔值(Booleans)、日期(dates)以及文本(text)。
实例
- 批量插入数据
没有手动插入映射,因此ElasticSearch
会为我们自动创建映射,这就意味着只要是文本就会为我们使用分词器分词。
POST /my_store/products/_bulk
{ "index": { "_id": 1 }}
{ "price" : 10, "productID" : "XHDK-A-1293-#fJ3" }
{ "index": { "_id": 2 }}
{ "price" : 20, "productID" : "KDKE-B-9947-#kL5" }
{ "index": { "_id": 3 }}
{ "price" : 30, "productID" : "JODL-X-1937-#pV7" }
{ "index": { "_id": 4 }}
{ "price" : 30, "productID" : "QQPX-R-3956-#aD8" }
查询数值
- 使用
constant_score
查询以非评分模式来执行term
查询并以一作为统一评分,这样返回的结果的评分全部是1 - 使用
constant_score
将term转化为过滤器查询
GET /my_store/products/_search
{
"query" : {
"constant_score" : {
"filter" : {
"term" : {
"price" : 20
}
}
}
}
}
//结果如下
{
"took": 1,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 1,
"hits": [
{
"_index": "my_store",
"_type": "products",
"_id": "2",
"_score": 1,
"_source": {
"price": 20,
"productID": "KDKE-B-9947-#kL5"
}
}
]
}
}
查询文本
- 文本怎样分词
- 大写字母转换为小写字母
- 复数变成单数
- 去掉特殊字符
- 由于term是精确查询,但是在查询文本的时候,很有可能这个文本已经进行了分词,但是term查询的时候搜索的词不分词,因此可能两个文本明明是一样的,但是却匹配不上。
GET /my_store/products/_search
{
"query" : {
"constant_score" : {
"filter" : {
"term" : {
"productID" : "XHDK-A-1293-#fJ3" //虽然和插入的数据一样,但是却查询不到
}
}
}
}
}
- 从上面的结果可以看到,由于term查询默认是不对搜索的词进行分词的,但是在查询的文本是分词的,因此这里肯定是查询不到的,我们可以使用分词分析器看看这个
productID
如何实现分词的,如下:
GET /my_store/_analyze
{
"field": "productID", //指定分词的域
"text": "XHDK-A-1293-fJ3-the" //文本内容
}
//结果如下:
{
"tokens": [
{
"token": "xhdk",
"start_offset": 0,
"end_offset": 4,
"type": "",
"position": 0
},
{
"token": "a",
"start_offset": 5,
"end_offset": 6,
"type": "",
"position": 1
},
{
"token": "1293",
"start_offset": 7,
"end_offset": 11,
"type": "",
"position": 2
},
{
"token": "fj3",
"start_offset": 12,
"end_offset": 15,
"type": "",
"position": 3
},
{
"token": "the",
"start_offset": 16,
"end_offset": 19,
"type": "",
"position": 4
}
]
}
- 从上面的结果可知:
- 在分词的过程中自动去掉了特殊字符,比如
-
和& - 大写字母全部转为小写
- 在分词的过程中自动去掉了特殊字符,比如
解决
- 如果需要使用term精确匹配查询文本,那么这个文本就不能使用分词器分词,因此需要手动创建索引的映射(mapping),如下:
DELETE my_store //先删除索引
PUT /my_store //手动指定映射
{
"mappings" : {
"products" : {
"properties" : {
"productID" : {
"type" : "string",
"index" : "not_analyzed" //不分词
}
}
}
}
}
- 此时如果再查询,那么就会精确匹配到这个信息了。
terms
- 对于多个关键字的查询,假设我们需要查询price在10,20,30中的其中一个即可,那么需要使用terms指定多组值
- 精确查询,不会使用分词器
GET /my_store/products/_search
{
"query":{
"terms":{
"price":[20,10,30]
}
}
}
指定文档数量 (from ,size)
- 假设我们需要对前两个文档进行查询,那么可以使用
from
和size
指定文档的数量,如下:
GET /my_store/products/_search
{
"from":0, //从第一文档开始
"size":2, //查询两个文档
"query":{
"terms":{
"price":[20,10,30]
}
}
}
返回指定的字段 _source
- 在使用查询的时候默认返回的是全部的字段,那么我们可以使用
_source
指定返回的字段
GET /lib/user/_search
{
"_source":["address","age"],
"query": {
"match_phrase": {
"address": "huibei,wuhan"
}
}
}
- 同时我们也可以排除不返回哪些字段,使用
exclude
即可
GET /lib/user/_search
{
"_source":{
"exclude": ["address","age"], //排除字段
"include": ["name","date"] //包含的字段
},
"query": {
"match_phrase": {
"address": "huibei,wuhan"
}
}
}
返回版本号
- 默认的查询返回版本号,我们可以在查询体中加上
version:true
即可
GET /my_store/products/_search
{
"version":true,
"from":0,
"size":2,
"query":{
"terms":{
"price":[20,10,30]
}
}
}
match查询
productId
GET /my_store/products/_search
{
"query" : {
"match" : {
"productID" : "XHDK-A-1293-#fJ3"
}
}
}
- 比如说我们要查找姓名是
zhaoliu
或者zhaoming
的,那么只需要使用match即可
GET /my_store/products/_search
{
"query" : {
"match" : {
"name" : "zhaoliu zhaoming" //会对这个短语进行分词,分出两个,之后去查询
}
}
}
match_all
- 查询所有
GET /my_store/products/_search
{
"query": {
"match_all": {
}
}
}
match_phrase
- 短语匹配查询
- 类似
match
查询,match_phrase
查询首先将查询字符串解析成一个词项列表,然后对这些词项进行搜索,但只保留那些包含 全部
搜索词项,且 位置
与搜索词项相同的文档。 比如对于quick fox
的短语搜索可能不会匹配到任何文档,因为没有文档包含的quick
词之后紧跟着fox
。 - 位置顺序必须一致
GET /lib/user/_search
{
"query": {
"match_phrase": {
"address": "huibei,wuhan"
}
}
}
- 获取你会觉得短语匹配太严格了,那么可以使用slop这个关键字指定相隔的步长,https://www.elastic.co/guide/cn/elasticsearch/guide/current/slop.html
排序
- 使用
sort
可以进行排序
GET /lib/user/_search
{
"_source":{
"exclude": ["address","name"],
"include": ["age","date"]
},
"query": {
"match_phrase": {
"address": "huibei,wuhan"
}
},
"sort": [ //指定排序
{
"age": { //对字段age进行排序
"order": "desc"
},
"address": { //address排序
"order": "asc"
}
}
]
}
range
-
https://www.elastic.co/guide/cn/elasticsearch/guide/current/_ranges.html
-
gt
:>
大于(greater than) lt
:<
小于(less than)gte
:>=
大于或等于(greater than or equal to)lte
:<=
小于或等于(less than or equal to)
日期查询
- 可以查询日期的范围,如下:
GET /lib/user/_search
{
"query": {
"range": {
"date": {
"gt": "2010-11-11", //大于
"lt": "2012-12-31" //小于
}
}
}
}
GET /lib/user/_search
{
"query": {
"range": {
"date": {
"gt":"now" //查询大于现在时间的文档
}
}
}
}
GET /lib/user/_search
{
"query": {
"range": {
"date": {
"gt":"now-1h" //查询距离现在一小时之内的文档,直接使用now减去一小时即可
}
}
}
}
GET /lib/user/_search
{
"query": {
"range": {
"date": {
"gt": "2010-11-11 00:00:00", //指定时分秒查询
"lt": "2012-12-31 00:00:00"
}
}
}
}
数字
GET /lib/user/_search
{
"query": {
"range": {
"price": {
"gt": 10, //数值范围查找
"lt": 20
}
}
}
}
字符串范围
range
查询同样可以处理字符串字段, 字符串范围可采用 字典顺序(lexicographically)
或字母顺序(alphabetically)。例如,下面这些字符串是采用字典序(lexicographically)排序的:- 5, 50, 6, B, C, a, ab, abb, abc, b
- 在倒排索引中的词项就是采取字典顺序(lexicographically)排列的,这也是字符串范围可以使用这个顺序来确定的原因。
"range" : {
"title" : {
"gte" : "a",
"lt" : "b"
}
}
wildcard查询
* ?
GET team/user/_search
{
"query": {
"wildcard": {
"name":"chen*"
}
}
}
GET team/user/_search
{
"query": {
"wildcard": {
"name":"chen?iabing"
}
}
}
模糊查询 fuzzy
- 假设我们需要查询
chenjiabing
这个名字,那么使用模糊查询的话,如果其中有个字符写错了,也是能够查询到的
GET team/user/_search
{
"query": {
"fuzzy": {
"name":"chejiabing"
}
}
}
高亮查询
GET team/user/_search
{
"query": {
"fuzzy": {
"name":"chejiabing"
}
},
"highlight": {
"pre_tags": [""], //指定包裹的标签前半部分,默认的是
"post_tags": [""], //指定后半部分
"fields": {
"name": {} //name字段高量
}
}
}
null值的查询
exists
这个语句用来查询存在值的信息,如果和must结合表示查询不为null的数据,如果must_not集合表示查询为null
的数据,如下:
//查询password=null的数据
GET ea/user/_search
{
"query": {
"bool": {
"must_not":{
"exists":{
"field":"password"
}
}
}
}
}
//查询password!=null的数据
GET ea/user/_search
{
"query": {
"bool": {
"must":{
"exists":{
"field":"password"
}
}
}
}
}
filter查询
- 缓存,不返回相关性,速度比query快
简单的过滤查询
- 使用
post_filter
GET /lib/user/_search
{
"post_filter": {
"term": {
"age":22
}
}
}
bool过滤查询
- 语法如下:
must
:所有的语句都 必须(must)
匹配,与AND
等价。must_not
:所有的语句都 不能(must not)
匹配,与NOT
等价。should
:至少有一个语句要匹配,与OR
等价。
{
"bool" : {
"must" : [],
"should" : [],
"must_not" : [],
}
}
- 其中的每一个部分都是可选的
实例
- must中的内容查询是并列的,相当于sql中的and,所有的条件都满足才可以
GET /lib/user/_search
{
"query": {
"bool": {
"must": [
{"term": {"age":22}},
{"match":{"address": "湖北"}}
]
}
}
}
GET /lib/user/_search
{
"post_filter": {
"bool": {
"should": [
{"term":{"name":"郑元梅"}},
{"term":{"age":33}}
],
"must_not": [
{"term":{"age":22}}
]
}
}
}
嵌套bool过滤查询
- 我们需要执行sql语句如下:
select * from user where name="郑元梅" or age=33 or(age=22 and price=33);
GET /lib/user/_search
{
"query": {
"bool": {
"should": [
{"term":{"name":"郑元梅"}},
{"term":{"age":33}},
{
"bool": {
"must": [
{"term":{"age":22},
{"term":{"price":33}}
}
]
}
}
]
}
}
}
范围过滤
GET /lib/user/_search { "post_filter": { "range": { "age": { "gte": 20, "lte": 21 } } } }
非空的过滤查询
select * from user where address is not null
GET /lib/user/_search { "query": { "bool": { "filter": { "exists": { "field": "address" } } } } }
聚合查询
- 在sql中有许多的聚合函数,那么在Elasticsearch中页存在这些聚合函数,比如sum,avg,count等等
GET /lib/user/_search { "size": 0, //在使用聚合的时候,默认还会返回全部的文档结果,如果不需要,可以使用size限制 "aggs": { "sum_age": { //sum_age 指定返回字段的名称 "sum": { //sum是指定的聚合函数的名称 "field": "age" //这里指定聚合的字段 } } } } GET /lib/user/_search { "size": 0, "aggs": { "avg_age": { "avg": { "field": "age" } } } } GET /lib/user/_search { "size": 0, "aggs": { "max_age": { "max": { "field": "age" } } } } GET /lib/user/_search { "size": 0, "aggs": { "min_age": { "min": { "field": "age" } } } } GET /lib/user/_search { "size": 0, "aggs": { "cardinality_age": { "cardinality": { //查询某个字段的基数,就是对应的字段有多少个不同的值 "field": "age" } } } }
- 分组(group),使用的是
terms
GET /lib/user/_search { "size": 0, "aggs": { "age_group": { "terms": { "field": "date" //按照日期进行分组 } } } } //结果如下: { "took": 6, "timed_out": false, "_shards": { "total": 5, "successful": 5, "skipped": 0, "failed": 0 }, "hits": { "total": 6, "max_score": 0, "hits": [] }, "aggregations": { "age_group": { "doc_count_error_upper_bound": 0, "sum_other_doc_count": 0, "buckets": [ { "key": 1352635200000, "key_as_string": "2012-11-11 12:00:00", "doc_count": 5 //分组的数量 }, { "key": 1352592000000, "key_as_string": "2012-11-11 00:00:00", "doc_count": 1 } ] } } }
- 对年龄是22岁的用户按照date进行分组,如下:
GET /lib/user/_search { "size": 0, "query": { "term": { "age": "22" } }, "aggs": { "age_group": { "terms": { "field": "date" } } } }
- 对年龄是22岁的用户按照date进行分组,并且计算每组的平均年龄
select *,avg(age) from user group by date;
GET /lib/user/_search { "query": { "term": { "age": "22" } }, "aggs": { "age_group": { "terms": { "field": "date" }, "aggs": { //直接在分组的聚合中,再次使用聚合求age的均值 "age_avg": { "avg": { "field": "age" } } } } } }
- 对年龄是22岁的用户按照date进行分组,并且计算每组的平均年龄,最后按照平均年龄进行排序
GET /lib/user/_search { "query": { "term": { "age": "22" } }, "aggs": { "age_group": { "terms": { "field": "date", "order": { "age_avg": "asc" //按照聚合查询的平均年龄进行升序排序 } }, "aggs": { "age_avg": { "avg": { "field": "age" } } } } } }
转自:https://www.colabug.com/4334463.html
感谢您的阅读,您的支持是我写博客动力。

浙公网安备 33010602011771号