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
sense查询语句示例:
GET /index_name/type_name/_search
{
"query": {
"match": {
"fruit": "apple"
}
},
"size": 100
}
一般使用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后面为查询语句
filter | query |
---|---|
relevance | boolean yes/no |
full text | exact values |
not cached | cached |
slower | faster |
执行顺序:filter first , then query remaining docs
加载过滤结果不需要消耗过多内存,如果其他查询用到同样的过滤结果,那么该查询将非常快 加载缓存与否主要区别在于是否保存过滤的结果,过虑的方式包含:term,terms,prefix,range,这些过滤 是默认加载缓存的,但 geo,script 过滤默认不加载缓存.and not or 这三种方式是不加载缓存的,但子语句可以是加载缓存的,我们可以设置_cache 参数取显示设置.
fields.raw:不进行分词,如一个字段为num ,如果要不分词匹配该字段下的值,则要写成num.raw,一般都要加上.raw,匹配会精确些
fieleds.std: 利用标准的 analyzer 进行分词(默认),包含大小写转换,停用词等过滤,与英文 analyzer不同的是,std 不会提取主干,比如 ‘jumping’,经过英文分类器之后,词语转换为 jump.默认的 analyzer 为标准分类器.
设置显示的条数, 默认为 10 条
GET /index_name/type_name/_search
{
"size": 5
}
说明: 以上语句为从index_name数据库中查出五条,未限定任何条件
GET /index_name/_search
{
"size": 20,
"fields": [
"fruit", "goods"
]
}
说明: 以上语句为查询二十条,只返回数据库中的fruit和goods字段相应的值,fields和size不分前后顺序,可以将fields写到size前面
_source用法与fields相同,功能也是用来限定某些特定字段,区别大致有两点:
示例:
GET /_search
{
"size": 20,
"partial_fields": {
"partial": {
"include": "p*"
}
}
}
默认情况下,在所有的字段下进行查询
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"
}
}
}
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
如果没有涉及 query 操作,在大多数情况下可以只用 filter 函数,以下两个查询方式的结果相同
GET /_search
{
"filter": {
"term": {
"fruit ": "apple"
}
}
}
说明: 只返回满足条件fruit下为apple值的结果
GET /_search
{
"size": 20,
"filter": {
"and": [
{
"term": {
"fruit": "apple"
}
},
{
"term": {
"eventType": "buy"
}
}
]
}
}
说明: 返回既满足条件fruit为apple又满足evenType为buy的结果
与上面的逻辑过滤相似,用法如下:
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的结果,其他逻辑条件类似
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字段的数据
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"
GET /_search
{
"size": 20,
"filter": {
"terms": {
"fruit": [
"apple",
"banana"
]
}
}
}
说明: 类似于
where fruit in (“apple”,”banana”)
terms是多个值匹配,放到列表中,term是一个值匹配,为一个字符串
GET /_search
{
"size": 20,
"filter": {
"regexp": {
"eventType": "bu.*"
}
}
}
说明: 具体正则符号见正则符号学习网
GET /_search
{
"size": 20,
"filter": {
"prefix": {
"eventType": "bu"
}
}
}
a limited filter limits the number of documents to execute on , 一般用不到
GET /_search
{
"size": 20,
"fields": [
"deviceId"
],
"filter": {
"limit": {
"value": 1
}
}
}
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 介绍:
1. 聚合操作,基于 query 的结果集上,所以做 aggs 的操作时单纯用 filter 是起不到作用的,类似于 sql 中的 group by 操作
2. aggs 涉及两个概念:metric(指标计算) & bucket(分箱)
GET /_search
{
"aggs": {
"res": {
"cardinality": {
"field": "fruit"
}
}
}
}
说明: res为结果的名字,可以自定义,cardinality为去重选项,返回结果为”aggregations”:{“res”: {“value”: 143}},最终结果为143
类似sql中的groupby
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,
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。
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"
}
}
}
}
}
}
安装elasticsearch模块:
sudo pip install elasticsearch
与 python 代码
# !/usr/bin/env python
# -*- coding:utf-8 -*-
# 声明模块
import sys
import elasticsearch
from elasticsearch import helpers
reload(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.scan
res = 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、search
res = 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