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"
    }
  }
}

排序

  • 使用 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

日期查询

  • 可以查询日期的范围,如下:
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
posted @ 2019-04-29 22:13  N神3  阅读(184)  评论(0)    收藏  举报