ElasticSearch从入门到精通(持续更新....)—多条件查询

583 阅读5分钟

这是我参与11月更文挑战的第10天,活动详情查看:2021最后一次更文挑战

ElasticSearch是一款高效的数据存储与查询工具,最近工作中用到java对es进行操作,在这里记录分享一下。

(持续更新中。。。)

一、简介

ElasticSearch智能搜索,分布式的搜索引擎;是ELK的一个组成,是一个产品,而且是非常完善的产品,ELK代表的是:E就是ElasticSearch,L就是Logstach,K就是kibana。

E:EalsticSearch 搜索和分析的功能。

L:Logstach 搜集数据的功能,类似于flume(使用方法几乎跟flume一模一样),是日志收集系统。

K:Kibana 数据可视化(分析),可以用图表的方式来去展示,文不如表,表不如图,是数据可视化平台。

二、全文检索

全文检索是指计算机索引程序通过扫描文章中的每一个词,对每一个词建立一个索引,指明该词在文章中出现的次数和位置,当用户查询时,检索程序就根据事先建立的索引进行查找,并将查找的结果反馈给用户的检索方式。这个过程类似于通过字典中的检索字表查字的过程。

全文检索的方法主要分为按字检索和按词检索两种。按字检索是指对于文章中的每一个字都建立索引,检索时将词分解为字的组合。对于各种不同的语言而言,字有不同的含义,比如英文中字与词实际上是合一的,而中文中字与词有很大分别。按词检索指对文章中的词,即语义单位建立索引,检索时按词检索,并且可以处理同义项等。英文等西方文字由于按照空白切分词,因此实现上与按字处理类似,添加同义处理也很容易。中文等东方文字则需要切分字词,以达到按词索引的目的,关于这方面的问题,是当前全文检索技术尤其是中文全文检索技术中的难点。

三、倒排索引

以前是根据ID查内容,倒排索引之后是根据内容查ID,然后再拿着ID去查询出来真正需要的东西。

反向索引又叫倒排索引,是根据文章内容中的关键字建立索引。 搜索引擎原理就是建立反向索引。 Elasticsearch 在 Lucene 的基础上进行封装,实现了分布式搜索引擎。 Elasticsearch 中的索引、类型和文档的概念比较重要,类似于 MySQL 中的数据库、表和行。 Elasticsearch 也是 Master-slave 架构,也实现了数据的分片和备份。 Elasticsearch 一个典型应用就是 ELK 日志分析系统。

四、多条件查询

查询 organization_id 为 208 和 event_type 为 007 的数据

curl -X GET 10.44.99.102:9200/situation-event/_search?pretty -d 
{
    "query": {
        "bool": {
            "must": [{
                "term": {
                    "organization_id": "208"
                }
            }, {
                "term": {
                    "event_type": "007"
                }
            }]
        }
    }
}

查询 organization_id 为 208 和 event_type 为 007 或者 008 的数据

curl -X GET 10.44.99.102:9200/situation-event/_search?pretty -d 
{
    "query": {
        "bool": {
            "must": [{
                "match_phrase": {
                    "organization_id": "208"
                }
            }],
            "should": [{
                    "match_phrase": {
                        "event_type": "007"
                    }
                },
                {
                    "match_phrase": {
                        "event_type": "008"
                    }
                }
            ],
            "minimum_should_match": 1
        }
    }
}

OR

curl -X GET 10.44.99.102:9200/situation-event/_search?pretty -d 
{
    "query": {
        "bool": {
            "must": [{
                "match_phrase": {
                    "organization_id": "208"
                }
            }],
            "should": [{
                    "terms": {
                        "event_type":[ "007", "008"]
                    }
                }
            ],
            "minimum_should_match": 1
        }
    }
}

数值范围查询

范围查询的符号

符号含义
gtegreater-than or equal to, 大于或等于
gtgreater-than, 大于
lteless-than or equal to, 小于或等于
ltless-than, 小于

需求: 查询商品中40 <= price <= 80的文档:

GET book_shop/_search
{
    "query": {
        "range": {
            "price": {
                "gte": 40,
                "lte": 80,
                "boost": 2.0	// 设置得分的权重值(提升值), 默认是1.0
            }
        }
    }
}

简单查询示例

需求: 查询网站中最近一天发布的博客:

GET website/_search
{
    "query": {
        "range": {
            "post_date": {
            	"gte": "now-1d/d",	// 当前时间的上一天, 四舍五入到最近的一天
            	"lt":  "now/d"		// 当前时间, 四舍五入到最近的一天
        	}
        }
    }
}

时区范围查询(time_zone)

如果日期field的格式允许, 也可以通过在日期值本身中指定时区, 从而将日期从另一个时区的时间转换为UTC时间, 或者为其指定特定的time_zone参数.

GET website/_search
{
    "query": {
        "range": {
            "post_date": {
                "gte": "2018-01-01 00:00:00",
                "lte": "now",
                "format": "yyyy-MM-dd hh:mm:ss",
                "time_zone": "+1:00"
            }
        }
    }
}

ES中的日期类型必须按照UTC时间格式存储, 所以, 上述的2018-01-01 00:00:00将被转换为2017-12-31T23:00:00 UTC.

日期格式详情参见:blog.csdn.net/xiangjai/ar…

排序查询:sort

降序:desc 升序 asc

GET zhifou/doc/_search { 
    "query": { 
        "match": { 
            "from": "gu" 
            } 
     }, 
     "sort":[
             { 
             "age": { "order": "desc" } 
            } 
      ] 
}

不是什么数据类型都能排序

那么,你可能会问,除了age,能不能以别的属性作为排序条件啊?来试试:

GET zhifou/chengyuan/_search
{
  "query": {
    "match_all": {}
  },
  "sort": [
    {
      "name": {
        "order": "asc"
      }
    }
  ]
}

报错!!!!

注意:在排序的过程中,只能使用可排序的属性进行排序。那么可以排序的属性有哪些呢?

  • 数字
  • 日期

其他的都不行!

聚合函数-以taskStatusCode分组,组名aaa,取20条

使用聚合查询(AggregationBuilders),可以直接在聚合里设置"size"来控制返回条数。

GET work_order_info/_search\
{\
  "size": 20,\
  "aggs": {\
    "aaa": {\
      "terms": {\
        "field""taskStatusCode"\
      }\
    }\
  }\
}

from+size 实现分页

from表示从第几行开始,size表示查询多少条文档。from默认为0,size默认为10。

注意:size的大小不能超过index.max_result_window这个参数的设置,默认为10,000。 我们发现查询结果最大只能到10000,这是因为Elasticsearch中的size的默认值在index.max_result_window 中设置,并且默认值就是10000。下面我们通过Elasticsearch的API设置index.max_result_window参数最大的读取行。

PUT _settings

{

"index": {

"max_result_window": "10000000"

}

}