Elasticsearch应用

一、介绍

ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。下面介绍了利用Python API接口进行数据查询,方便其他系统的调用。

安装API

pip3 install elasticsearch

 

建立es连接

无用户名密码状态

from elasticsearch import Elasticsearch
es = Elasticsearch([{'host':'10.10.13.12','port':9200}])

 

默认的超时时间是10秒,如果数据量很大,时间设置更长一些。如果端口是9200,直接写IP即可。代码如下:

es = Elasticsearch(['10.10.13.12'], timeout=3600)

 

用户名密码状态

如果Elasticsearch开启了验证,需要用户名和密码

es = Elasticsearch(['10.10.13.12'], http_auth=('xiao', '123456'), timeout=3600)

 

数据检索功能

es.search(index='logstash-2015.08.20', q='http_status_code:5* AND server_name:"web1"', from_='124119')

 

常用参数
  • index - 索引名
  • q - 查询指定匹配 使用Lucene查询语法
  • from_ - 查询起始点  默认0
  • doc_type - 文档类型
  • size - 指定查询条数 默认10
  • field - 指定字段 逗号分隔
  • sort - 排序  字段:asc/desc
  • body - 使用Query DSL
  • scroll - 滚动查询

 

统计查询功能

语法同search大致一样,但只输出统计值

es.count(index='logstash-2015.08.21', q='http_status_code:500')

输出:

{'_shards':{'failed':0, 'successful':5, 'total':5}, 'count':17042}

 

17042 就是统计值!

 

知识扩展

滚动demo

# Initialize the scroll
page = es.search(
    index ='yourIndex',
    doc_type ='yourType',
    scroll ='2m',
    search_type ='scan',
    size =1000,
    body ={
    # Your query's body
})
 
sid = page['_scroll_id']
scroll_size = page['hits']['total']
 
# Start scrolling
while(scroll_size >0):
    print "Scrolling..."
    page = es.scroll(scroll_id = sid, scroll ='2m')
    # Update the scroll ID
    sid = page['_scroll_id']
    # Get the number of results that we returned in the last scroll
    scroll_size = len(page['hits']['hits'])
    print "scroll size: "+ str(scroll_size)
    # Do something with the obtained page

以上demo实现了一次取若干数据,数据取完之后结束,不会获取到最新更新的数据。我们滚动完之后想获取最新数据怎么办?滚动的时候会有一个统计值,如total: 5。跳出循环之后,我们可以用_from参数定位到5开始滚动之后的数据。

 

但是我用的不是这个,用的是以下方法,链接如下:

https://www.cnblogs.com/blue163/p/8126156.html

 

在下面的内容中,我会详细介绍此代码如何使用!

 

二、Query DSL

range过滤器查询范围

gt: > 大于
lt: < 小于
gte: >= 大于或等于
lte: <= 小于或等于

 

示例代码1

"range":{
    "money":{
        "gt":20,
        "lt":40
    }
}

 

时间范围

最近时间段

比如我要查询最近1分钟的

"range": {
    '@timestamp': {'gt': 'now-1m'}
}

 

最新1小时

"range": {
    '@timestamp': {'gt': 'now-1h'}
}

 

最新1天的

"range": {
    '@timestamp': {'gt': 'now-1d'}
}

 

指定时间段

那么问题来了,它是根据当前时间来计算最近的时间。但是有些情况下,我需要制定时间范围,精确到分钟

假设需要查询早上8点到9点的数据,可以这样

"range": {
    '@timestamp': {
        "gt" : "{}T{}:00:00".format("2018-12-17","08"),
        "lt": "{}T{}:59:59".format("2018-12-17","09"),
        "time_zone": "Asia/Shanghai"
    }
}

 

注意:日期和小时之间,有一个字母T来间隔。不能用空格!

time_zone 表示时区,如果默认的时区不会,可能会影响查询结果!

 

bool组合过滤器

must:所有分句都必须匹配,与 AND 相同。
must_not:所有分句都必须不匹配,与 NOT 相同。
should:至少有一个分句匹配,与 OR 相同。

 

示例代码

{
    "bool":{
      "must":[],
      "should":[],
      "must_not":[],
    }
}

 

term过滤器

term单过滤

{
    "terms":{
      "money":20
    }
}

 

表示money包含20的记录

 

terms复数版本

允许多个匹配条件

{
    "terms":{
      "money": [20,30]
    }
}

 

表示money包含20或者30的记录

 

结合bool+term来举一个实际的例子:

查询path字段中包含applogs最近1分钟的记录

复制代码
"bool": {
    "must": [
        {
            "terms": {
                "path": [
                    "applogs",
                ]
            }
        },
        {
            "range": {
                '@timestamp': {'gt': 'now-1m'}
            }
        }
    ]
}
复制代码

 

这里使用了terms复数版本,可以随时添加多个条件!

正则查询 

{
    "regexp": {
        "http_status_code": "5.*"
    }
}

 

match查询

match 精确匹配

{
    "match":{
      "email":"123456@qq.com"
    }
}

 

multi_match 多字段搜索

{
    "multi_match":{
      "query":"11",
      "fields":["Tr","Tq"]
    }
}
posted @ 2019-12-11 14:27  洛丶丶丶  阅读(275)  评论(0编辑  收藏  举报