ElasticSearch使用简介

来源:互联网 发布:行客软件管家 编辑:程序博客网 时间:2024/06/06 06:55

一、ElasticSearch概要

ElasticSearch is a search server based on Lucene. It provides a distributed, multitenant-capable full-text search engine with a RESTful web interface and schema-free JSON documents. —-wiki

(一)ElasticSearch的使用方法

1、使用谷歌浏览器 Sense 插件

  • 下载Sense插件安装包,并解压缩;
  • 打开谷歌浏览器,找到更多工具->扩展程序,将sense文件夹拖到那里即可,在改网页界面上输入查询语句即可。

sense查询语句示例:

GET /index_name/type_name/_search{   "query": {      "match": {         "fruit": "apple"      }   },   "size": 100}

2、使用curl语句

一般使用sense界面进行查询,比较简单,还有种方法是curl命令,在终端命令行输入,语句示例:

curl -XGET localost:9200/index_name/type_name/_search -d '{  "query": {      "match": {         "fruit": "apple"      }   },   "size": 100}'

说明:
* localhost:9200为地址,
* index_name为数据库名称,
* type_name为表,
* _search为搜索选项,
* -d后面为查询语句

(二)ElasticSearch特点

  1. Real-Time:查询分析速度快
  2. Distributed:分布式
  3. High Availability:高可用,检测坏结点,自动组织和重新平衡数据
  4. multitenancy:一个集群可以建设多个 indeces
  5. full-text search:全文检索,query api
  6. document-oriented:基于 JSON 形式的文档,文档中的 fields 默认建立索引
  7. per-operation persistence:数据安全,一个文档改变的话,日志将分发给多个结点

(三)基本概念

  1. index:类似于关系型数据库中的 database(数据库)
  2. type:类似于关系型数据库中的 table(表)
  3. document:类似于关系型数据库中的 record(记录)
  4. fields:类似于关系型数据库中的列、字段
  5. mapping: how a document should be mapped to the Search Engine ,including its searchable,characteristics such as which fields are searchable and how they are tokenized
  6. analyzer:分词,去除停用词,空格等操作

二、搜索理论

(一)filter 和 query 区别

filter query relevance boolean yes/no full text exact values not cached cached slower faster

执行顺序:filter first , then query remaining docs

(二)filter 和 cached 关系

加载过滤结果不需要消耗过多内存,如果其他查询用到同样的过滤结果,那么该查询将非常快 加载缓存与否主要区别在于是否保存过滤的结果,过虑的方式包含:term,terms,prefix,range,这些过滤 是默认加载缓存的,但 geo,script 过滤默认不加载缓存.and not or 这三种方式是不加载缓存的,但子语句可以是加载缓存的,我们可以设置_cache 参数取显示设置.

(三)fields.raw 以及 fields.std

fields.raw:不进行分词,如一个字段为num ,如果要不分词匹配该字段下的值,则要写成num.raw,一般都要加上.raw,匹配会精确些
fieleds.std: 利用标准的 analyzer 进行分词(默认),包含大小写转换,停用词等过滤,与英文 analyzer不同的是,std 不会提取主干,比如 ‘jumping’,经过英文分类器之后,词语转换为 jump.默认的 analyzer 为标准分类器.

三、DSL语法

(一)限定条数size

设置显示的条数, 默认为 10 条

GET /index_name/type_name/_search {   "size": 5}

说明: 以上语句为从index_name数据库中查出五条,未限定任何条件

(二)输出特定字段fields、_source

1、fields

GET /index_name/_search {   "size": 20,   "fields": [      "fruit", "goods"   ]}

说明: 以上语句为查询二十条,只返回数据库中的fruit和goods字段相应的值,fields和size不分前后顺序,可以将fields写到size前面

2、_source

_source用法与fields相同,功能也是用来限定某些特定字段,区别大致有两点:

  • fields过滤已经存储得字段的时候更加快速.(Fields is best used for fields that are stored. When not stored it behaves similar to source. So in case all the fields you want in result are all stored it would be faster filtering using “fields” instead of source.)
  • _source返回的字段范围更广,而fields只返回特定字段下的值
    比如:car下有color、price字段,数据格式为:{‘car’: {‘color’: ‘red’, ‘price’: [‘3w’, ‘5w’]}};

示例:

  • 用fields限定字段’fields’: [‘car.color’]可以返回,但是’fields’: [‘car.price’]就不能返回,因为car.price为列表;
    相应的若用’_source’: [‘car.price’]就能够获取相应的值,故若遇到列表类型的值用_source;类似得,’fields’:[‘car’]不会返回,而’_source’:[‘car’]返回car下的所有
  • 二者返回的内容不同。fields返回的为{‘car.color’: ‘red’},_source返回的是{‘car’ : {‘color’ : ‘red’}}

(三)模糊化选择字段partial_fields

GET /_search{   "size": 20,   "partial_fields": {      "partial": {         "include": "p*"      }   }}

(四)查询字符串query_string

默认情况下,在所有的字段下进行查询

GET /_search{   "size": 20,   "query": {      "query_string": {         "query": "13500001111"      }   }}

若想再特定字段下查找相应字符串,则可需限定字段,如下

GET /_search{   "size": 20,   "query": {      "query_string": {         "default_field": "num",         "query": "13500001111"      }   }}

说明: 在num字段下查找13500001111

query_string实现不分词,代码如下:

GET /_search{    "query": {        "query_string": {           "default_field": "*.raw",           "query": "13500001111"        }    }}

(五)限定条件操作(过滤)之filter

filtered query: #combine another query with any filter,exclude as many document as you can with a filter ,then query just the documents that remain

1、filter

如果没有涉及 query 操作,在大多数情况下可以只用 filter 函数,以下两个查询方式的结果相同

GET /_search {   "filter": {      "term": {         "fruit ": "apple"      }   }}

说明: 只返回满足条件fruit下为apple值的结果

2、逻辑过滤之 or filter & and filter & not filter

GET /_search {   "size": 20,   "filter": {      "and": [         {            "term": {               "fruit": "apple"            }         },         {            "term": {               "eventType": "buy"            }         }      ]   }}

说明: 返回既满足条件fruit为apple又满足evenType为buy的结果

3、逻辑过滤之bool filter

与上面的逻辑过滤相似,用法如下:

GET /_search {   "filter": {      "bool": {         "must": [            {               "term": {                  "eventType": "buy"               }            }         ],         "should": [            {               "term": {                  "fruit": "apple"               }            },            {               "term": {                  "fruit": "banana"               }            }         ]      }   },   "size": 5}

说明: 在bool条件下,有must(满足以下所有条件)、must_not(不满足以下条件)、should(满足以下条件之一),以上语句为返回满足eventType为buy的,fruit为apple或者为banana的结果,其他逻辑条件类似

4、exists & missing #过滤字段存在以及缺失数据

GET /_search {   "size": 20,   "fields": [      "deviceId"   ],   "filter": {      "exists": {         "field": "deviceId"      }   }}

说明: 查询存在deviceId字段的数据,并返回deviceId下的值

GET /_search{   "size": 20,   "fields": [      "deviceId"   ],   "filter": {      "missing": {         "field": "deviceId"      }   }}

说明: 查询deviceId字段下为缺失值的数据

GET /_search {   "size": 20,   "fields": [      "deviceId"   ],   "filter": {      "not": {         "exists": {            "field": "deviceId"         }      }   }}

说明: 查询不存在deviceId字段的数据

5、range filter 限定范围

GET /_search {   "size": 20,   "filter": {      "range": {         "eventOccurTime": {            "gte": "2015-05-01 00:00:00",            "lte": "2015-05-02 00:00:00"         }      }   }}

说明: gte和lte可以换为from和to,都表示范围,大于小于
类似于条件语句

where eventOccurTime between"2015-05-01 00:00:00" and "2015-05-02 00:00:00" 

6、terms filter 多个值匹配

GET /_search {   "size": 20,   "filter": {      "terms": {         "fruit": [            "apple",            "banana"         ]      }   }}

说明: 类似于

where fruit in (“apple”,”banana”)

terms是多个值匹配,放到列表中,term是一个值匹配,为一个字符串

7、regexp filter 正则过滤 类似于SQL中的模糊选择

GET /_search {   "size": 20,   "filter": {      "regexp": {         "eventType": "bu.*"      }   }}

说明: 具体正则符号见正则符号学习网

8、prefix filter 前部边界匹配

GET /_search {   "size": 20,   "filter": {      "prefix": {         "eventType": "bu"      }   }}

9、limit filter

a limited filter limits the number of documents to execute on , 一般用不到

GET /_search {   "size": 20,   "fields": [      "deviceId"   ],   "filter": {      "limit": {         "value": 1      }   }}

(六)限定条件操作(过滤)之filtered

filtered为query下的过滤语句,其下有两个附加查询语句,一个为query(见上文),一个为filter(见上文),其查询逻辑为过滤掉相应条件之后,进行query查询,

GET /_search{   "query": {      "filtered": {         "query": {            "default_field": "num",            "query_string": {               "query": "13500001111"            }         },         "filter": {            "bool": {               "must": [                  {                     "term": {                        "fruit": "apple"                     }                  }               ]            }         }      }   },   "size": 20}

说明: 在fruit必须为apple的条件下,在num字段下查询存在13500001111的某些结果
ps:有些查询不用query,只用filter即可,比如上面的查询语句可以写成如下语句:

{    "query": {        "filtered": {           "filter": {               "bool": {                   "must": [                      {                          "term": {                             "fruit": "apple"                          }                      },                      {                          "term": {                             "num": "13500001111"                          }                      }                   ]               }           }        }    },    "size": 20}

(七)聚合计算aggs

aggs 介绍:
1. 聚合操作,基于 query 的结果集上,所以做 aggs 的操作时单纯用 filter 是起不到作用的,类似于 sql 中的 group by 操作
2. aggs 涉及两个概念:metric(指标计算) & bucket(分箱)

1、去重统计 cardinality

GET /_search {   "aggs": {      "res": {         "cardinality": {            "field": "fruit"         }      }   }}

说明: res为结果的名字,可以自定义,cardinality为去重选项,返回结果为”aggregations”:{“res”: {“value”: 143}},最终结果为143

2、分类返回terms

类似sql中的groupby

(1)单个聚合

GET /_search {   "aggs": {      "res": {         "terms": {            "field": "fruit"         }      }   }}

说明: res为结果的名字,返回结果为每个partnerCode对应的事件数量,结果为:”aggregations”: {“res”: {“buckets”: [{“key”: “apple”,”doc_count”: 3},{“key”: “banana”,”doc_count”: 5}]}},apple的数量为3,banana的数量为5,

(2)嵌套聚合

GET /_search {   "aggs": {      "res_a": {         "terms": {            "field": "fruit"         },         "aggs": {            "res_b": {               "terms": {                  "field": "num"               }            }         }      }   }}

说明: 在返回每个fruit事件数量的基础上,返回每个fruit事件中num的聚合结果,结果为:”aggregations”: {“res_a”: {“buckets”: [{“key”: “apple”,”doc_count”: 3}],”res_b”: {“buckets”: [{“key”: “18311110000”,”doc_count”: 6},{“key”: “13511110000”,”doc_count”: 3}]}},即res_a中既有partnercode的buckets还有res_b,apple下有18311110000和13511110000两个手机号,每个手机号的记录为6和3。

(3)ranges聚合

GET /_search {   "size": 20,   "aggs": {      "res": {         "range": {            "field": "payAmount",            "ranges": [               {                  "to": 50               },               {                  "from": 50,                  "to": 100               },               {                  "from": 100               }            ]         }      }   }}

aggs学习网址:http://blog.csdn.net/dm_vincent/article/details/42407823

(八)其他

第二个 aggs 与 filter 的层级相同

GET /_search {   "size": 20,   "aggs": {      "res": {         "filter": {            "term": {               "partnerCode": "apple"            }         },         "aggs": {            "avg_res": {               "avg": {                  "field": "payAmount"               }            }         }      }   }}

四、Python 与 ElasticSearch 的交互

安装elasticsearch模块:

sudo pip install elasticsearch

与 python 代码

# !/usr/bin/env python # -*- coding:utf-8 -*- # 声明模块import sysimport elasticsearchfrom elasticsearch import helpersreload(sys)sys.setdefaultencoding('utf-8')# 写es查询语句es_query = {   "size": 10,   "query": {      "query_string": {         "default_field": "*.std",         "query": "1314520"      }   }} # 连接地址es = elasticsearch.Elasticsearch(['localhost:9200'])# 查询有两种方法helps.scan和search# 1、helps.scanres = helpers.scan(es, index='index_name', doc_type=’type_name’, query=es_query, scroll='1m',request_timeout=999999) # 说明:scan是对满足语句的结果进行扫描,全部返回下来,结果为一个生成器需要解析,scroll为滚屏时间参数# Scan的结果解析:for re in res:     print re# 2、searchres = es.search(index='index_name', doc_type=’type_name’, body=es_query, request_timeout=999999,params={“search_type”:”query_and_fetch”}) # 说明:search返回的结果为字典不是生成器,和在sense上查询返回的结果相同,信息比较全,size限定1则返回1条,而scan是将所有结果全部返回,# search多用在进行聚合查询时,可以直接返回结果,但其较消耗资源,可能对数据库产生影响,故一般用scan进行查询,获取结果后进一步解析,而若要使用search要加上参数Params={“search_type”:”query_and_fetch”},防止影响数据库的稳定。# Search的结果可以直接打印出来print res

学习资源

  1. 官方网址
  2. Elasticsearch 权威指南(中文版)
  3. elasticsearch中文社区
  4. aggs学习网址
  5. 正则学习网址
1 0
原创粉丝点击