ES基本概念和常用REST查询


一、相关概念

1.1 倒排索引

    Elasticsearch使用倒排索引来达到加速检索的目的。

    倒排索引:根据属性值来确定记录位置

    倒排索引源于实际应用中需要根据属性的值来查找记录。这种索引表中的每一项都包括一个属性值和具有该属性值的各记录的地址。由于不是由记录来确定属性值,而是由属性值来确定记录的位置,因而称为倒排索引(inverted index)。带有倒排索引的文件我们称为倒排索引文件,简称倒排文件(inverted file)。

    在Elasticsearch中,每一个字段的数据都是默认被索引的。也就是说,每个字段专门有一个反向索引用于快速检索。而且,与其它数据库不同,它可以在同一个查询中利用所有的这些反向索引,以惊人的速度返回结果。

    通常,我们可以认为对象(object)文档(document)是等价相通的。不过,他们还是有所差别:对象(Object)是一个JSON结构体——类似于哈希、hashmap、字典或者关联数组;对象(Object)中还可能包含其他对象(Object)。 在Elasticsearch中,文档(document)这个术语有着特殊含义。它特指最顶层结构或者根对象(root object)序列化成的JSON数据(以唯一ID标识并存储于Elasticsearch中)。

1.2 分析器

    当我们索引(index)一个文档,全文字段会被分析为单独的词来创建倒排索引。不过,当我们在全文字段搜索(search)时,我们要让查询字符串经过同样的分析流程处理,以确保这些词在索引中存在。

    全文查询我们将在稍后讨论,理解每个字段是如何定义的,这样才可以让它们做正确的事:

  • 当你查询全文(full text)字段,查询将使用相同的分析器来分析查询字符串,以产生正确的词列表。
  • 当你查询一个确切值(exact value)字段,查询将不分析查询字符串,但是你可以自己指定。

1.3 指定分析器

    当Elasticsearch在你的文档中探测到一个新的字符串字段,它将自动设置它为全文string字段并用standard分析器分析。

    你不可能总是想要这样做。也许你想使用一个更适合这个数据的语言分析器。或者,你只想把字符串字段当作一个普通的字段——不做任何分析,只存储确切值,就像字符串类型的用户ID或者内部状态字段或者标签。

    为了达到这种效果,我们必须通过映射(mapping)人工设置这些字段。

小提示

错误的映射,例如把age字段映射为string类型而不是integer类型,会造成查询结果混乱。

要检查映射类型,而不是假设它是正确的!

1.4 查询和过滤--性能差异

    使用过滤语句得到的结果集 -- 一个简单的文档列表,快速匹配运算并存入内存是十分方便的, 每个文档仅需要1个字节。这些缓存的过滤结果集与后续请求的结合使用是非常高效的。

    查询语句不仅要查找相匹配的文档,还需要计算每个文档的相关性,所以一般来说查询语句要比 过滤语句更耗时,并且查询结果也不可缓存。

    幸亏有了倒排索引,一个只匹配少量文档的简单查询语句在百万级文档中的查询效率会与一条经过缓存 的过滤语句旗鼓相当,甚至略占上风。 但是一般情况下,一条经过缓存的过滤查询要远胜一条查询语句的执行效率。

    过滤语句的目的就是缩小匹配的文档结果集,所以需要仔细检查过滤条件。

 1.5 查询和过滤--什么情况下使用

原则上来说,使用查询语句做全文本搜索或其他需要进行相关性评分的时候,剩下的全部用过滤语句

前面我们讲到的是关于结构化查询语句,事实上我们可以使用两种结构化语句: 结构化查询(Query DSL)和结构化过滤(Filter DSL)。 查询与过滤语句非常相似,但是它们由于使用目的不同而稍有差异。

一条过滤语句会询问每个文档的字段值是否包含着特定值:

  • created 的日期范围是否在 2013 到 2014 ?

  • status 字段中是否包含单词 "published" ?

  • lat_lon 字段中的地理位置与目标点相距是否不超过10km ?

一条查询语句与过滤语句相似,但问法不同:

查询语句会询问每个文档的字段值与特定值的匹配程度如何?

查询语句的典型用法是为了找到文档:

  • 查找与 full text search 这个词语最佳匹配的文档

  • 查找包含单词 run ,但是也包含runsrunningjog 或 sprint的文档

  • 同时包含着 quickbrown 和 fox --- 单词间离得越近,该文档的相关性越高

  • 标识着 lucenesearch 或 java --- 标识词越多,该文档的相关性越高

一条查询语句会计算每个文档与查询语句的相关性,会给出一个相关性评分 _score,并且 按照相关性对匹配到的文档进行排序。 这种评分方式非常适用于一个没有完全配置结果的全文本搜索。

二、最重要的查询过滤语句

2.1 term 过滤

    term主要用于精确匹配哪些值,比如数字,日期,布尔值或 not_analyzed的字符串(未经分析的文本数据类型):

2.2 terms 过滤

    terms 跟 term 有点类似,但 terms 允许指定多个匹配条件。 如果某个字段指定了多个值,那么文档需要一起去做匹配:

2.3 range 过滤

    range过滤允许我们按照指定范围查找一批数据:

2.4 exists 和 missing 过滤

    exists 和 missing 过滤可以用于查找文档中是否包含指定字段或没有某个字段,类似于SQL语句中的IS_NULL条件

2.5 bool 过滤

    bool 过滤可以用来合并多个过滤条件查询结果的布尔逻辑,它包含以下操作符:

    must :: 多个查询条件的完全匹配,相当于 and

    must_not :: 多个查询条件的相反匹配,相当于 not

    should :: 至少有一个查询条件匹配, 相当于 or

    这些参数可以分别继承一个过滤条件或者一个过滤条件的数组:

2.6 match_all 查询

    使用match_all 可以查询到所有文档,是没有查询条件下的默认语句。

2.7 match 查询

    match查询是一个标准查询,不管你需要全文本查询还是精确查询基本上都要用到它。

2.8 multi_match 查询

    multi_match查询允许你做match查询的基础上同时搜索多个字段:

2.9 bool 查询

    bool 查询与 bool 过滤相似,用于合并多个查询子句。不同的是,bool 过滤可以直接给出是否匹配成功, 而bool 查询要计算每一个查询子句的 _score (相关性分值)。

    must:: 查询指定文档一定要被包含。

    must_not:: 查询指定文档一定不要被包含。

    should:: 查询指定文档,有则可以为文档相关性加分。

2.10 查询与过滤条件的合并

    查询语句和过滤语句可以放在各自的上下文中。 在 ElasticSearch API 中我们会看到许多带有 query 或filter 的语句。 这些语句既可以包含单条 query 语句,也可以包含一条 filter 子句。 换句话说,这些语句需要首先创建一个queryfilter的上下文关系。

    复合查询语句可以加入其他查询子句,复合过滤语句也可以加入其他过滤子句。 通常情况下,一条查询语句需要过滤语句的辅助,全文本搜索除外。

    所以说,查询语句可以包含过滤子句,反之亦然。 以便于我们切换 query 或 filter 的上下文。这就要求我们在读懂需求的同时构造正确有效的语句。

三、常用REST请求示例

    针对es对外开放的http接口,下面列举除了一些常用的rest请求示例,同时它们在tcp接口中都有对应的java api实现

3.1 查询集群信息

localhost:9200

3.2 查看集群健康状态

localhost:9200/_cat/health?v

3.3  查看集群节点

localhost:9200/_cat/nodes?v

3.4 查看集群分片

localhost:9200/_cat/indices?v

3.5 创建索引

PUT localhost:9200/lulijun

3.6 索引文档

PUT localhost:9200/poi/doc/8?pretty

 

{
"poi_id": 2,
"poi_name": "3_name",
"time":1,
"price": 5
}

3.7 查询文档

localhost:9200/lulijun/doc/1?pretty

3.8 删除索引

DELETE localhost:9200/lulijun

3.9 更新文档

POST localhost:9200/lulijun/doc/1/_update

 

{
"doc":{
"name":"lulijun02"
}
}

3.10 以脚本更新文档

localhost:9200/lulijun/doc/1/_update

 

{
"script":"ctx._source.gener = 'male'"
}

3.11 删除文档

DELETE localhost:9200/lulijun/doc/1

3.12 批量操作

POST localhost:9200/lulijun/doc/_bulk

 

{"index":{"_id":"1"}}
{"name": "lulijun01","gender":"female" }
{"index":{"_id":"2"}}
{"name": "lulijun02", "gender":"male" }


3.13 查询全部-request param

localhost:9200/_search?q=*

3.14 查询全部-request body

POST localhost:9200/poi/_search

 

{
"query": { "match_all": {} }
}

3.15 limit

localhost:9200/lulijun/_search

 

{
"query": { "match_all": {} },
"size" : 1
}

3.16 Paging

 

localhost:9200/poi/_search

 


 

{
"query": { "match_all": {} },
"from" : 1,
"size":1
}

3.17 指定返回字段

POST localhost:9200/lulijun/_search

{
"query":{
"match_all":{}
},
"_source":["gender"]
}

3.18 match查询

localhost:9200/lulijun/_search

 

{
"query":{
"match":{
"gender":"male"
}
}
}

3.19 bool查询-must

localhost:9200/lulijun/_search

 

{
"query":{
"bool":{
"must":[
{
"match":{
"gender":"male"
}
},
{
"match":{
"name":"lulijun"
}
}
]
}
}
}

3.20 bool查询-should

localhost:9200/lulijun/_search

 

{
"query":{
"bool":{
"should":[
{
"match":{
"gender":"male"
}
},
{
"match":{
"name":"lulijun"
}
}
]
}
}
}


3.21 bool查询-must not

localhost:9200/lulijun/_search

 

{
"query":{
"bool":{
"must_not":[
{
"match":{
"gender":"xx"
}
},
{
"match":{
"name":"xy"
}
}
]
}
}
}


3.22 groupby+count

localhost:9200/poi/_search

 

{
"size":0,
"aggs":{
"group_by_state":{
"terms":{
"field":"poi_id"
}
}
}
}


3.23 groupby+sum

localhost:9200/poi/_search

{
"aggregations": {
"poi_id": {
"terms": {
"field": "poi_id",
"size": 2
},
"aggregations": {
"poi_name": {
"terms": {
"field": "time",
"size": 200
},
"aggregations": {
"SUM(price)": {
"sum": {
"field": "price"
}
}
}
}
}
}
}
}

3.24 script field

localhost:9200/poi/_search

 

{
"from": 0,
"size": 100,
"query":{
"bool":{
"must":[
{
"match":{
"poi_id":1
}
}
]
}
},
"aggregations": {
"poi_id": {
"terms": {
"script": {
"inline": "doc['poi_id'].value + 1"
}
},
"aggregations": {
"price": {
"sum": {
"field": "price"
}
}
}
}
}
}


  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值