访问ES最简单示例

这些天架了一个ES集群,用来分析积累了海量日志数据。我用sphinx写了一个简单文档,发布在内网。下面是复制过来的部分内容,不幸的是很多格式信息都丢失了。做了点简单修改,去掉了敏感信息。

///////////////////////////////////////////////////////////

本示例仅示范最为基础的应用,协助读者调通最简单的查询。 详细灵活的使用方法非本文档能够覆盖,需参见官方详细文档或咨询你常用的搜索引擎。

  1. 使用curl命令行工具
  2. 使用es官方python库
    1. RESTful接口
    2. 官方python库

使用curl命令行工具

NOTICE:
[*略去较为敏感的鉴权部分*]
  • 在访问日志中检索一个keyword,无论keyword出现在哪个字段中。 如下示例:所有文档,superuser出现在其中任意字段中都会被召回。注意酌情更换URI中的参数。 实际上,把_all替换成user_name,则只在user_name字段中检索。这里使用的是lucene语法, 参见:https://lucene.apache.org/core/2_9_4/queryparsersyntax.html
1
curl https://endpoint/_search?q=_all:superuser
  • 使用ES的DSL语法,在访问日志中检索出现在指定字段中的keyword。 如下示例:superuser出现在user_name字段中。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
curl https://endpoint/_search?pretty -H "Content-Type: application/json" -X POST -d '
{
   "query":{
       "bool":{
             "filter":[
                 { "term":{ "user_name": "superuser" } }
             ]
       }
   }
}'

上述检索方法使用了ES中的filter语法,filter是较快的一种查询方式。如果需要检索的字段需要分词,则只能使用 match语法,如下:

1
2
3
4
5
6
7
8
curl ./kamus.key https://endpoint/_search?pretty -H "Content-Type: application/json" -X POST -d '
{
   "query":{
       "match":{
             {"user_name": "superuser"}
       }
   }
}'
  • 为检索增加时间限制 如需要指定时间区间:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
curl "https://endpoint/_search?pretty" -d '
{
  "query":{
       "bool":{
               "must":{
                    "match":{
                                "user_name":"superuser"
                            }
               },
               "filter":{
                     "range":{
                          "req_time":{
                                        "gte":"2017-01-01 00:00:00",
                                        "lt":"2017-08-08 00:00:00"
                                     }
                       }
                }
        }
  }
} '
  • 分页 ES的分页使用”from”和”size”参数。例如,每页10条,返回第1页。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
curl "https://endpoint/_search?pretty"  -d '
{
     "from": 0,
     "size": 10,
     "query": {
         "term": {
              "user_name": "superuser"
         }
     }
}
'

由于ES的实现机制,ES并不鼓励使用分页,在size较大且from的页码也较大时,ES可能无法及时响应。

  • 其他高级应用 如bool操作,以及复杂灵活的查询条件组合请参加官网文档。

使用es官方python库

懒得打字了,看官方文档吧: https://elasticsearch-py.readthedocs.io/

It’s not lupus 是个什么梗,什么意思呢

著名黑客于旸, AKA tkyu, tk教主在论坛里的头像是一个狰狞面孔的人,头像下面有一行英文:

It’s not Lupus

这句话是什么意思呢?原来来自2007年福克斯Fox的一部电视连续剧 House
剧中主人公是普林斯敦大学教学医院的医学天才(Dr. House),他反传统并且不愿意与人交往。他的工作伙伴是一些年轻的医生。
年轻的医生在搞不清楚病人发病原因的时候,就认为这可能是Lupus(狼疮)。因为Lupus这个病需要好几年才能够被确诊。这时,Dr House就说: “It’s not lupus”或“It’s never lupus”。直到有一天,确实出现了一个Lupus案例。
我猜,tk教主引用It’s not Lupus这句话可能暗指他也是Dr House一样的天才吧~

发现linux命令/工具find的一个”bug”

今天用find命令找一个目录下面所有大小小于1K的普通文件. 我的命令是这么写的:

$ find ~ -type f -a -size -1K | wc -l

发现得到的数字明显比预想的小很多。但命令没错呀~~百思不得其解之下,又试了一下另一种写法。这时,就正常了,真奇怪啊~~

$ find ~ -type f -a -size -1024c | wc -l

这次就正常了!!!
我反复查文档:

c for bytes
K for Kilobytes (units of 1024 bytes)

对啊~~没错啊。 1K就是1024byte。哪里出问题了,哪出出错了呢?难道是linux的bug吗?我换了一个发行版的linux,发现还是同样的情况。这就郁闷了~~
再次查看文档,这次详细读文档了!终于发现问题所在了:

The + and – prefixes signify greater than and less than, as usual. Bear in mind that the size is rounded up to the next
unit. Therefore -size -1M is not equivalent to -size -1048576c. The former only matches empty files, the latter matches
files from 1 to 1,048,575 bytes.

至此,真相大白!~~原来呢
用K或M这些单位时,尺寸会被向上取整(is rounded up to the next unit)。这样一个100字节的文件被向上取整到1K的文件,就没有命中-1K了
这里非常奇怪的是“向上取整”。